ci-queue 0.21.1 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +6 -0
- data/ci-queue.gemspec +1 -1
- data/lib/ci/queue/bisect.rb +4 -0
- data/lib/ci/queue/common.rb +4 -0
- data/lib/ci/queue/configuration.rb +4 -2
- data/lib/ci/queue/redis/acknowledge.lua +2 -0
- data/lib/ci/queue/redis/base.rb +6 -6
- data/lib/ci/queue/redis/build_record.rb +17 -15
- data/lib/ci/queue/redis/grind_record.rb +9 -7
- data/lib/ci/queue/redis/release.lua +16 -0
- data/lib/ci/queue/redis/requeue.lua +6 -0
- data/lib/ci/queue/redis/reserve.lua +2 -0
- data/lib/ci/queue/redis/reserve_lost.lua +2 -0
- data/lib/ci/queue/redis/test_time_record.rb +10 -11
- data/lib/ci/queue/redis/worker.rb +44 -8
- data/lib/ci/queue/version.rb +1 -1
- data/lib/minitest/queue/runner.rb +15 -0
- data/lib/rspec/queue.rb +9 -0
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 652049f77362ba8fa3fd01b79a0260c5ff17ba678751ee2424de463afe035d38
|
4
|
+
data.tar.gz: 745b2c493350d2315a10f36147d5d3b4cc74df74d5f38e82d2250f10be219d4a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d47070eca76cfd6191cc003191af153ba2b40596dca4c3408325389a110ae1b798e99dcdb7e27b33c23d5bf457d6eab003dd608602a5df9de38741408d7bb48a
|
7
|
+
data.tar.gz: 0d2f4f69af4fc3714dbd6d5660d0e3106890a7bd5cef5782bae41847aa1552b35a8c9af6e77b7d8d18264b2100463062cb205f7ed45cef7646aeb2ff4ffe3bd3
|
data/README.md
CHANGED
@@ -70,3 +70,9 @@ rspec-queue --queue redis://example.com --timeout 600 --report
|
|
70
70
|
#### Limitations
|
71
71
|
|
72
72
|
Because of how `ci-queue` executes the examples, `before(:all)` and `after(:all)` hooks are not supported. `rspec-queue` will explicitly reject them.
|
73
|
+
|
74
|
+
## Custom Redis Expiry
|
75
|
+
|
76
|
+
`ci-queue` expects the Redis server to have an [eviction policy](https://redis.io/docs/manual/eviction/#eviction-policies) of `allkeys-lru`.
|
77
|
+
|
78
|
+
You can also use `--redis-ttl` to set a custom expiration time for all CI Queue keys, this defaults to 8 hours (28,800 seconds)
|
data/ci-queue.gemspec
CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.add_development_dependency 'bundler'
|
33
33
|
spec.add_development_dependency 'rake'
|
34
34
|
spec.add_development_dependency 'minitest', ENV.fetch('MINITEST_VERSION', '~> 5.11')
|
35
|
-
spec.add_development_dependency 'rspec', '~> 3.
|
35
|
+
spec.add_development_dependency 'rspec', '~> 3.10'
|
36
36
|
spec.add_development_dependency 'redis'
|
37
37
|
spec.add_development_dependency 'simplecov', '~> 0.12'
|
38
38
|
spec.add_development_dependency 'minitest-reporters', '~> 1.1'
|
data/lib/ci/queue/bisect.rb
CHANGED
data/lib/ci/queue/common.rb
CHANGED
@@ -5,7 +5,7 @@ module CI
|
|
5
5
|
attr_accessor :timeout, :worker_id, :max_requeues, :grind_count, :failure_file
|
6
6
|
attr_accessor :requeue_tolerance, :namespace, :failing_test, :statsd_endpoint
|
7
7
|
attr_accessor :max_test_duration, :max_test_duration_percentile, :track_test_duration
|
8
|
-
attr_accessor :max_test_failed
|
8
|
+
attr_accessor :max_test_failed, :redis_ttl
|
9
9
|
attr_reader :circuit_breakers
|
10
10
|
attr_writer :seed, :build_id
|
11
11
|
attr_writer :queue_init_timeout
|
@@ -18,6 +18,7 @@ module CI
|
|
18
18
|
seed: env['CIRCLE_SHA1'] || env['BUILDKITE_COMMIT'] || env['TRAVIS_COMMIT'] || env['HEROKU_TEST_RUN_COMMIT_VERSION'] || env['SEMAPHORE_GIT_SHA'],
|
19
19
|
flaky_tests: load_flaky_tests(env['CI_QUEUE_FLAKY_TESTS']),
|
20
20
|
statsd_endpoint: env['CI_QUEUE_STATSD_ADDR'],
|
21
|
+
redis_ttl: env['CI_QUEUE_REDIS_TTL']&.to_i || 8 * 60 * 60,
|
21
22
|
)
|
22
23
|
end
|
23
24
|
|
@@ -34,7 +35,7 @@ module CI
|
|
34
35
|
namespace: nil, seed: nil, flaky_tests: [], statsd_endpoint: nil, max_consecutive_failures: nil,
|
35
36
|
grind_count: nil, max_duration: nil, failure_file: nil, max_test_duration: nil,
|
36
37
|
max_test_duration_percentile: 0.5, track_test_duration: false, max_test_failed: nil,
|
37
|
-
queue_init_timeout: nil
|
38
|
+
queue_init_timeout: nil, redis_ttl: 8 * 60 * 60
|
38
39
|
)
|
39
40
|
@build_id = build_id
|
40
41
|
@circuit_breakers = [CircuitBreaker::Disabled]
|
@@ -55,6 +56,7 @@ module CI
|
|
55
56
|
@worker_id = worker_id
|
56
57
|
self.max_consecutive_failures = max_consecutive_failures
|
57
58
|
self.max_duration = max_duration
|
59
|
+
@redis_ttl = redis_ttl
|
58
60
|
end
|
59
61
|
|
60
62
|
def queue_init_timeout
|
@@ -1,8 +1,10 @@
|
|
1
1
|
-- AUTOGENERATED FILE DO NOT EDIT DIRECTLY
|
2
2
|
local zset_key = KEYS[1]
|
3
3
|
local processed_key = KEYS[2]
|
4
|
+
local owners_key = KEYS[3]
|
4
5
|
|
5
6
|
local test = ARGV[1]
|
6
7
|
|
7
8
|
redis.call('zrem', zset_key, test)
|
9
|
+
redis.call('hdel', owners_key, test) -- Doesn't matter if it was reclaimed by another workers
|
8
10
|
return redis.call('sadd', processed_key, test)
|
data/lib/ci/queue/redis/base.rb
CHANGED
@@ -21,16 +21,16 @@ module CI
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def size
|
24
|
-
redis.multi do
|
25
|
-
|
26
|
-
|
24
|
+
redis.multi do |transaction|
|
25
|
+
transaction.llen(key('queue'))
|
26
|
+
transaction.zcard(key('running'))
|
27
27
|
end.inject(:+)
|
28
28
|
end
|
29
29
|
|
30
30
|
def to_a
|
31
|
-
redis.multi do
|
32
|
-
|
33
|
-
|
31
|
+
redis.multi do |transaction|
|
32
|
+
transaction.lrange(key('queue'), 0, -1)
|
33
|
+
transaction.zrange(key('running'), 0, -1)
|
34
34
|
end.flatten.reverse.map { |k| index.fetch(k) }
|
35
35
|
end
|
36
36
|
|
@@ -22,9 +22,9 @@ module CI
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def pop_warnings
|
25
|
-
warnings = redis.multi do
|
26
|
-
|
27
|
-
|
25
|
+
warnings = redis.multi do |transaction|
|
26
|
+
transaction.lrange(key('warnings'), 0, -1)
|
27
|
+
transaction.del(key('warnings'))
|
28
28
|
end.first
|
29
29
|
|
30
30
|
warnings.map { |p| Marshal.load(p) }
|
@@ -35,21 +35,22 @@ module CI
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def record_error(id, payload, stats: nil)
|
38
|
-
redis.pipelined do
|
39
|
-
|
38
|
+
redis.pipelined do |pipeline|
|
39
|
+
pipeline.hset(
|
40
40
|
key('error-reports'),
|
41
41
|
id.dup.force_encoding(Encoding::BINARY),
|
42
42
|
payload.dup.force_encoding(Encoding::BINARY),
|
43
43
|
)
|
44
|
-
|
44
|
+
pipeline.expire(key('error-reports'), config.redis_ttl)
|
45
|
+
record_stats(stats, pipeline: pipeline)
|
45
46
|
end
|
46
47
|
nil
|
47
48
|
end
|
48
49
|
|
49
50
|
def record_success(id, stats: nil)
|
50
|
-
redis.pipelined do
|
51
|
-
|
52
|
-
record_stats(stats)
|
51
|
+
redis.pipelined do |pipeline|
|
52
|
+
pipeline.hdel(key('error-reports'), id.dup.force_encoding(Encoding::BINARY))
|
53
|
+
record_stats(stats, pipeline: pipeline)
|
53
54
|
end
|
54
55
|
nil
|
55
56
|
end
|
@@ -65,8 +66,8 @@ module CI
|
|
65
66
|
end
|
66
67
|
|
67
68
|
def fetch_stats(stat_names)
|
68
|
-
counts = redis.pipelined do
|
69
|
-
stat_names.each { |c|
|
69
|
+
counts = redis.pipelined do |pipeline|
|
70
|
+
stat_names.each { |c| pipeline.hvals(key(c)) }
|
70
71
|
end
|
71
72
|
sum_counts = counts.map do |values|
|
72
73
|
values.map(&:to_f).inject(:+).to_f
|
@@ -75,9 +76,9 @@ module CI
|
|
75
76
|
end
|
76
77
|
|
77
78
|
def reset_stats(stat_names)
|
78
|
-
redis.pipelined do
|
79
|
+
redis.pipelined do |pipeline|
|
79
80
|
stat_names.each do |stat_name|
|
80
|
-
|
81
|
+
pipeline.hdel(key(stat_name), config.worker_id)
|
81
82
|
end
|
82
83
|
end
|
83
84
|
end
|
@@ -86,10 +87,11 @@ module CI
|
|
86
87
|
|
87
88
|
attr_reader :config, :redis
|
88
89
|
|
89
|
-
def record_stats(stats)
|
90
|
+
def record_stats(stats, pipeline: redis)
|
90
91
|
return unless stats
|
91
92
|
stats.each do |stat_name, stat_value|
|
92
|
-
|
93
|
+
pipeline.hset(key(stat_name), config.worker_id, stat_value)
|
94
|
+
pipeline.expire(key(stat_name), config.redis_ttl)
|
93
95
|
end
|
94
96
|
end
|
95
97
|
|
@@ -11,12 +11,13 @@ module CI
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def record_error(payload, stats: nil)
|
14
|
-
redis.pipelined do
|
15
|
-
|
14
|
+
redis.pipelined do |pipeline|
|
15
|
+
pipeline.lpush(
|
16
16
|
key('error-reports'),
|
17
17
|
payload.force_encoding(Encoding::BINARY),
|
18
18
|
)
|
19
|
-
|
19
|
+
pipeline.expire(key('error-reports'), config.redis_ttl)
|
20
|
+
record_stats(stats, pipeline: pipeline)
|
20
21
|
end
|
21
22
|
nil
|
22
23
|
end
|
@@ -34,8 +35,8 @@ module CI
|
|
34
35
|
end
|
35
36
|
|
36
37
|
def fetch_stats(stat_names)
|
37
|
-
counts = redis.pipelined do
|
38
|
-
stat_names.each { |c|
|
38
|
+
counts = redis.pipelined do |pipeline|
|
39
|
+
stat_names.each { |c| pipeline.hvals(key(c)) }
|
39
40
|
end
|
40
41
|
stat_names.zip(counts.map { |values| values.map(&:to_f).inject(:+).to_f }).to_h
|
41
42
|
end
|
@@ -54,10 +55,11 @@ module CI
|
|
54
55
|
['build', config.build_id, *args].join(':')
|
55
56
|
end
|
56
57
|
|
57
|
-
def record_stats(stats)
|
58
|
+
def record_stats(stats, pipeline: redis)
|
58
59
|
return unless stats
|
59
60
|
stats.each do |stat_name, stat_value|
|
60
|
-
|
61
|
+
pipeline.hset(key(stat_name), config.worker_id, stat_value)
|
62
|
+
pipeline.expire(key(stat_name), config.redis_ttl)
|
61
63
|
end
|
62
64
|
end
|
63
65
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
-- AUTOGENERATED FILE DO NOT EDIT DIRECTLY
|
2
|
+
local zset_key = KEYS[1]
|
3
|
+
local worker_queue_key = KEYS[2]
|
4
|
+
local owners_key = KEYS[3]
|
5
|
+
|
6
|
+
-- owned_tests = {"SomeTest", "worker:1", "SomeOtherTest", "worker:2", ...}
|
7
|
+
local owned_tests = redis.call('hgetall', owners_key)
|
8
|
+
for index, owner_or_test in ipairs(owned_tests) do
|
9
|
+
if owner_or_test == worker_queue_key then -- If we owned a test
|
10
|
+
local test = owned_tests[index - 1]
|
11
|
+
redis.call('zadd', zset_key, "0", test) -- We expire the lease immediately
|
12
|
+
return nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
return nil
|
@@ -3,12 +3,18 @@ local processed_key = KEYS[1]
|
|
3
3
|
local requeues_count_key = KEYS[2]
|
4
4
|
local queue_key = KEYS[3]
|
5
5
|
local zset_key = KEYS[4]
|
6
|
+
local worker_queue_key = KEYS[5]
|
7
|
+
local owners_key = KEYS[6]
|
6
8
|
|
7
9
|
local max_requeues = tonumber(ARGV[1])
|
8
10
|
local global_max_requeues = tonumber(ARGV[2])
|
9
11
|
local test = ARGV[3]
|
10
12
|
local offset = ARGV[4]
|
11
13
|
|
14
|
+
if redis.call('hget', owners_key, test) == worker_queue_key then
|
15
|
+
redis.call('hdel', owners_key, test)
|
16
|
+
end
|
17
|
+
|
12
18
|
if redis.call('sismember', processed_key, test) == 1 then
|
13
19
|
return false
|
14
20
|
end
|
@@ -3,6 +3,7 @@ local queue_key = KEYS[1]
|
|
3
3
|
local zset_key = KEYS[2]
|
4
4
|
local processed_key = KEYS[3]
|
5
5
|
local worker_queue_key = KEYS[4]
|
6
|
+
local owners_key = KEYS[5]
|
6
7
|
|
7
8
|
local current_time = ARGV[1]
|
8
9
|
|
@@ -10,6 +11,7 @@ local test = redis.call('rpop', queue_key)
|
|
10
11
|
if test then
|
11
12
|
redis.call('zadd', zset_key, current_time, test)
|
12
13
|
redis.call('lpush', worker_queue_key, test)
|
14
|
+
redis.call('hset', owners_key, test, worker_queue_key)
|
13
15
|
return test
|
14
16
|
else
|
15
17
|
return nil
|
@@ -2,6 +2,7 @@
|
|
2
2
|
local zset_key = KEYS[1]
|
3
3
|
local processed_key = KEYS[2]
|
4
4
|
local worker_queue_key = KEYS[3]
|
5
|
+
local owners_key = KEYS[4]
|
5
6
|
|
6
7
|
local current_time = ARGV[1]
|
7
8
|
local timeout = ARGV[2]
|
@@ -11,6 +12,7 @@ for _, test in ipairs(lost_tests) do
|
|
11
12
|
if redis.call('sismember', processed_key, test) == 0 then
|
12
13
|
redis.call('zadd', zset_key, current_time, test)
|
13
14
|
redis.call('lpush', worker_queue_key, test)
|
15
|
+
redis.call('hset', owners_key, test, worker_queue_key) -- Take ownership
|
14
16
|
return test
|
15
17
|
end
|
16
18
|
end
|
@@ -19,38 +19,37 @@ module CI
|
|
19
19
|
attr_reader :redis
|
20
20
|
|
21
21
|
def record_test_time(test_name, duration)
|
22
|
-
redis.pipelined do
|
23
|
-
|
22
|
+
redis.pipelined do |pipeline|
|
23
|
+
pipeline.lpush(
|
24
24
|
test_time_key(test_name),
|
25
25
|
duration.to_s.force_encoding(Encoding::BINARY),
|
26
26
|
)
|
27
|
+
pipeline.expire(test_time_key(test_name), config.redis_ttl)
|
27
28
|
end
|
28
29
|
nil
|
29
30
|
end
|
30
31
|
|
31
32
|
def record_test_name(test_name)
|
32
|
-
redis.pipelined do
|
33
|
-
|
33
|
+
redis.pipelined do |pipeline|
|
34
|
+
pipeline.lpush(
|
34
35
|
all_test_names_key,
|
35
36
|
test_name.dup.force_encoding(Encoding::BINARY),
|
36
37
|
)
|
38
|
+
pipeline.expire(all_test_names_key, config.redis_ttl)
|
37
39
|
end
|
38
40
|
nil
|
39
41
|
end
|
40
42
|
|
41
43
|
def fetch_all_test_names
|
42
|
-
values = redis.pipelined do
|
43
|
-
|
44
|
+
values = redis.pipelined do |pipeline|
|
45
|
+
pipeline.lrange(all_test_names_key, 0, -1)
|
44
46
|
end
|
45
47
|
values.flatten.map(&:to_s)
|
46
48
|
end
|
47
49
|
|
48
50
|
def fetch_test_time(test_name)
|
49
|
-
|
50
|
-
|
51
|
-
redis.lrange(key, 0, -1)
|
52
|
-
end
|
53
|
-
values.flatten.map(&:to_f)
|
51
|
+
key = test_time_key(test_name)
|
52
|
+
redis.lrange(key, 0, -1).map(&:to_f)
|
54
53
|
end
|
55
54
|
|
56
55
|
def all_test_names_key
|
@@ -53,6 +53,10 @@ module CI
|
|
53
53
|
sleep 0.05
|
54
54
|
end
|
55
55
|
end
|
56
|
+
redis.pipelined do |pipeline|
|
57
|
+
pipeline.expire(key('worker', worker_id, 'queue'), config.redis_ttl)
|
58
|
+
pipeline.expire(key('processed'), config.redis_ttl)
|
59
|
+
end
|
56
60
|
rescue *CONNECTION_ERRORS
|
57
61
|
end
|
58
62
|
|
@@ -92,7 +96,7 @@ module CI
|
|
92
96
|
raise_on_mismatching_test(test_key)
|
93
97
|
eval_script(
|
94
98
|
:acknowledge,
|
95
|
-
keys: [key('running'), key('processed')],
|
99
|
+
keys: [key('running'), key('processed'), key('owners')],
|
96
100
|
argv: [test_key],
|
97
101
|
) == 1
|
98
102
|
end
|
@@ -104,7 +108,14 @@ module CI
|
|
104
108
|
|
105
109
|
requeued = config.max_requeues > 0 && global_max_requeues > 0 && eval_script(
|
106
110
|
:requeue,
|
107
|
-
keys: [
|
111
|
+
keys: [
|
112
|
+
key('processed'),
|
113
|
+
key('requeues-count'),
|
114
|
+
key('queue'),
|
115
|
+
key('running'),
|
116
|
+
key('worker', worker_id, 'queue'),
|
117
|
+
key('owners'),
|
118
|
+
],
|
108
119
|
argv: [config.max_requeues, global_max_requeues, test_key, offset],
|
109
120
|
) == 1
|
110
121
|
|
@@ -112,6 +123,15 @@ module CI
|
|
112
123
|
requeued
|
113
124
|
end
|
114
125
|
|
126
|
+
def release!
|
127
|
+
eval_script(
|
128
|
+
:release,
|
129
|
+
keys: [key('running'), key('worker', worker_id, 'queue'), key('owners')],
|
130
|
+
argv: [],
|
131
|
+
)
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
|
115
135
|
private
|
116
136
|
|
117
137
|
attr_reader :index
|
@@ -144,7 +164,13 @@ module CI
|
|
144
164
|
def try_to_reserve_test
|
145
165
|
eval_script(
|
146
166
|
:reserve,
|
147
|
-
keys: [
|
167
|
+
keys: [
|
168
|
+
key('queue'),
|
169
|
+
key('running'),
|
170
|
+
key('processed'),
|
171
|
+
key('worker', worker_id, 'queue'),
|
172
|
+
key('owners'),
|
173
|
+
],
|
148
174
|
argv: [Time.now.to_f],
|
149
175
|
)
|
150
176
|
end
|
@@ -152,7 +178,12 @@ module CI
|
|
152
178
|
def try_to_reserve_lost_test
|
153
179
|
lost_test = eval_script(
|
154
180
|
:reserve_lost,
|
155
|
-
keys: [
|
181
|
+
keys: [
|
182
|
+
key('running'),
|
183
|
+
key('completed'),
|
184
|
+
key('worker', worker_id, 'queue'),
|
185
|
+
key('owners'),
|
186
|
+
],
|
156
187
|
argv: [Time.now.to_f, timeout],
|
157
188
|
)
|
158
189
|
|
@@ -167,13 +198,18 @@ module CI
|
|
167
198
|
@total = tests.size
|
168
199
|
|
169
200
|
if @master = redis.setnx(key('master-status'), 'setup')
|
170
|
-
redis.multi do
|
171
|
-
|
172
|
-
|
173
|
-
|
201
|
+
redis.multi do |transaction|
|
202
|
+
transaction.lpush(key('queue'), tests) unless tests.empty?
|
203
|
+
transaction.set(key('total'), @total)
|
204
|
+
transaction.set(key('master-status'), 'ready')
|
205
|
+
|
206
|
+
transaction.expire(key('queue'), config.redis_ttl)
|
207
|
+
transaction.expire(key('total'), config.redis_ttl)
|
208
|
+
transaction.expire(key('master-status'), config.redis_ttl)
|
174
209
|
end
|
175
210
|
end
|
176
211
|
register
|
212
|
+
redis.expire(key('workers'), config.redis_ttl)
|
177
213
|
rescue *CONNECTION_ERRORS
|
178
214
|
raise if @master
|
179
215
|
end
|
data/lib/ci/queue/version.rb
CHANGED
@@ -22,6 +22,9 @@ module Minitest
|
|
22
22
|
def initialize(argv)
|
23
23
|
@queue_config = CI::Queue::Configuration.from_env(ENV)
|
24
24
|
@command, @argv = parse(argv)
|
25
|
+
if Minitest.respond_to?(:seed=)
|
26
|
+
Minitest.seed = @queue_config.seed.to_i
|
27
|
+
end
|
25
28
|
end
|
26
29
|
|
27
30
|
def run!
|
@@ -81,6 +84,10 @@ module Minitest
|
|
81
84
|
# Let minitest's at_exit hook trigger
|
82
85
|
end
|
83
86
|
|
87
|
+
def release_command
|
88
|
+
queue.release!
|
89
|
+
end
|
90
|
+
|
84
91
|
def grind_command
|
85
92
|
invalid_usage!('No list to grind provided') if grind_list.nil?
|
86
93
|
invalid_usage!('No grind count provided') if grind_count.nil?
|
@@ -483,6 +490,14 @@ module Minitest
|
|
483
490
|
end
|
484
491
|
end
|
485
492
|
|
493
|
+
help = <<~EOS
|
494
|
+
Defines how long the test report remain after the test run, in seconds.
|
495
|
+
Defaults to 28,800 (8 hours)
|
496
|
+
EOS
|
497
|
+
opts.on("--redis-ttl SECONDS", Integer, help) do |time|
|
498
|
+
queue.config.redis_ttl = time
|
499
|
+
end
|
500
|
+
|
486
501
|
opts.separator ""
|
487
502
|
opts.separator " retry: Replays a previous run in the same order."
|
488
503
|
|
data/lib/rspec/queue.rb
CHANGED
@@ -157,6 +157,15 @@ module RSpec
|
|
157
157
|
queue_config.max_consecutive_failures = Integer(max)
|
158
158
|
end
|
159
159
|
|
160
|
+
help = <<~EOS
|
161
|
+
Defines how long the test report remain after the test run, in seconds.
|
162
|
+
Defaults to 28,800 (8 hours)
|
163
|
+
EOS
|
164
|
+
parser.separator ""
|
165
|
+
parser.on("--redis-ttl SECONDS", Integer, help) do |time|
|
166
|
+
queue.config.redis_ttl = time
|
167
|
+
end
|
168
|
+
|
160
169
|
parser
|
161
170
|
end
|
162
171
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ci-queue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.23.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Boussier
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-06-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 3.
|
61
|
+
version: '3.10'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 3.
|
68
|
+
version: '3.10'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: redis
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -187,6 +187,7 @@ files:
|
|
187
187
|
- lib/ci/queue/redis/grind.rb
|
188
188
|
- lib/ci/queue/redis/grind_record.rb
|
189
189
|
- lib/ci/queue/redis/grind_supervisor.rb
|
190
|
+
- lib/ci/queue/redis/release.lua
|
190
191
|
- lib/ci/queue/redis/requeue.lua
|
191
192
|
- lib/ci/queue/redis/reserve.lua
|
192
193
|
- lib/ci/queue/redis/reserve_lost.lua
|
@@ -238,7 +239,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
238
239
|
- !ruby/object:Gem::Version
|
239
240
|
version: '0'
|
240
241
|
requirements: []
|
241
|
-
rubygems_version: 3.
|
242
|
+
rubygems_version: 3.3.3
|
242
243
|
signing_key:
|
243
244
|
specification_version: 4
|
244
245
|
summary: Distribute tests over many workers using a queue
|