rspecq 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -1
- data/README.md +31 -2
- data/bin/rspecq +8 -1
- data/lib/rspecq/formatters/failure_recorder.rb +8 -1
- data/lib/rspecq/queue.rb +8 -0
- data/lib/rspecq/reporter.rb +7 -2
- data/lib/rspecq/version.rb +1 -1
- data/lib/rspecq/worker.rb +5 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 86b8792f2ff107cbfb1e67b881724c535df7730804feec7e4813f4690795fac1
|
4
|
+
data.tar.gz: bbd5b78cf7919b653446b00c0748c0ea0d9fca32f69e40e7dd439b3396042dec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29ee44880ef2d654cd8faeeeb7bcdee2f7ff2b468a22a51a3831d6a175a31246e0cd2206ce012eaa3c1a2ad3aad319360baa10f10d3b84745e7ee9e58fdf3b7b
|
7
|
+
data.tar.gz: d8cd7a9515a25a9b8679acffa99f3b8f19764ff7e23079921677aa40b1941cb6fbce05dbad813f308d68d460f7c06b97a453de2622ee8060161033f65c889189
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
Breaking changes are prefixed with a "[BREAKING]" label.
|
4
|
+
|
3
5
|
## master (unreleased)
|
4
6
|
|
5
|
-
|
7
|
+
## 0.6.0 (2021-03-23)
|
8
|
+
|
9
|
+
- New cli parameter `seed`.
|
10
|
+
The seed is passed to the RSpec command.
|
6
11
|
|
7
12
|
## 0.5.0 (2021-02-05)
|
8
13
|
|
data/README.md
CHANGED
@@ -79,6 +79,29 @@ OPTIONS:
|
|
79
79
|
-v, --version Print the version and exit.
|
80
80
|
```
|
81
81
|
|
82
|
+
You can set most options using ENV variables:
|
83
|
+
|
84
|
+
```shell
|
85
|
+
$ RSPECQ_BUILD=123 RSPECQ_WORKDER=foo1 rspecq spec/
|
86
|
+
```
|
87
|
+
|
88
|
+
### Supported ENV variables
|
89
|
+
|
90
|
+
| Name | Desc |
|
91
|
+
| --- | --- |
|
92
|
+
| `RSPECQ_BUILD` | Build ID |
|
93
|
+
| `RSPECQ_WORKER` | Worker ID |
|
94
|
+
| `RSPECQ_SEED` | RSpec seed |
|
95
|
+
| `RSPECQ_REDIS` | Redis HOST |
|
96
|
+
| `RSPECQ_UPDATE_TIMINGS` | Timings |
|
97
|
+
| `RSPECQ_FILE_SPLIT_THRESHOLD` | File split threshold |
|
98
|
+
| `RSPECQ_REPORT` | Report |
|
99
|
+
| `RSPECQ_REPORT_TIMEOUT` | Report Timeout |
|
100
|
+
| `RSPECQ_MAX_REQUEUES` | Max requests |
|
101
|
+
| `RSPECQ_QUEUE_WAIT_TIMEOUT` | Queue wait timeout |
|
102
|
+
| `RSPECQ_REDIS_URL` | Redis URL |
|
103
|
+
| `RSPECQ_FAIL_FAST` | Fail fast |
|
104
|
+
|
82
105
|
### Sentry integration
|
83
106
|
|
84
107
|
RSpecQ can optionally emit build events to a
|
@@ -90,7 +113,6 @@ This is convenient for monitoring important warnings/errors that may impact
|
|
90
113
|
build times, such as the fact that no previous timings were found and
|
91
114
|
therefore job scheduling was effectively random for a particular build.
|
92
115
|
|
93
|
-
|
94
116
|
## How it works
|
95
117
|
|
96
118
|
The core design is almost identical to ci-queue so please refer to its
|
@@ -117,7 +139,7 @@ For example, a single file may need 10 minutes to run while all other
|
|
117
139
|
files finish after 8 minutes. This would cause all but one workers to be
|
118
140
|
sitting idle for 2 minutes.
|
119
141
|
|
120
|
-
To overcome this issue, RSpecQ can
|
142
|
+
To overcome this issue, RSpecQ can split files which their execution time is
|
121
143
|
above a certain threshold (set with the `--file-split-threshold` option)
|
122
144
|
and instead schedule them as individual examples.
|
123
145
|
|
@@ -216,6 +238,13 @@ To enable verbose output in the tests:
|
|
216
238
|
$ RSPECQ_DEBUG=1 bundle exec rake
|
217
239
|
```
|
218
240
|
|
241
|
+
## Redis
|
242
|
+
|
243
|
+
RSpecQ by design doesn't expire its keys from Redis. It is left to the user
|
244
|
+
to configure the Redis server to do so; see
|
245
|
+
[Using Redis as an LRU cache](https://redis.io/topics/lru-cache) for more info.
|
246
|
+
|
247
|
+
You can do this from a configuration file or with `redis-cli`.
|
219
248
|
|
220
249
|
## License
|
221
250
|
|
data/bin/rspecq
CHANGED
@@ -38,9 +38,14 @@ OptionParser.new do |o|
|
|
38
38
|
opts[:worker] = v
|
39
39
|
end
|
40
40
|
|
41
|
+
o.on("--seed SEED", "The RSpec seed. Passing the seed can be helpful in " \
|
42
|
+
"many ways i.e reproduction and testing.") do |v|
|
43
|
+
opts[:seed] = v
|
44
|
+
end
|
45
|
+
|
41
46
|
o.on("-r", "--redis HOST", "Redis host to connect to " \
|
42
47
|
"(default: #{DEFAULT_REDIS_HOST}).") do |v|
|
43
|
-
puts "--redis is deprecated. Use --redis-host or --redis-url instead"
|
48
|
+
puts "DEPRECATION: --redis is deprecated. Use --redis-host or --redis-url instead"
|
44
49
|
opts[:redis_host] = v
|
45
50
|
end
|
46
51
|
|
@@ -109,6 +114,7 @@ end.parse!
|
|
109
114
|
|
110
115
|
opts[:build] ||= ENV["RSPECQ_BUILD"]
|
111
116
|
opts[:worker] ||= ENV["RSPECQ_WORKER"]
|
117
|
+
opts[:seed] ||= ENV["RSPECQ_SEED"]
|
112
118
|
opts[:redis_host] ||= ENV["RSPECQ_REDIS"] || DEFAULT_REDIS_HOST
|
113
119
|
opts[:timings] ||= env_set?("RSPECQ_UPDATE_TIMINGS")
|
114
120
|
opts[:file_split_threshold] ||= Integer(ENV["RSPECQ_FILE_SPLIT_THRESHOLD"] || 9_999_999)
|
@@ -154,5 +160,6 @@ else
|
|
154
160
|
worker.max_requeues = opts[:max_requeues]
|
155
161
|
worker.queue_wait_timeout = opts[:queue_wait_timeout]
|
156
162
|
worker.fail_fast = opts[:fail_fast]
|
163
|
+
worker.seed = Integer(opts[:seed]) if opts[:seed]
|
157
164
|
worker.work
|
158
165
|
end
|
@@ -30,7 +30,14 @@ module RSpecQ
|
|
30
30
|
def example_failed(notification)
|
31
31
|
example = notification.example
|
32
32
|
|
33
|
+
rerun_cmd = "bin/rspec --seed #{RSpec.configuration.seed} #{example.location_rerun_argument}"
|
34
|
+
|
33
35
|
if @queue.requeue_job(example.id, @max_requeues)
|
36
|
+
|
37
|
+
# Save the rerun command for later. It will be used if this is
|
38
|
+
# a flaky test for more user-friendly reporting.
|
39
|
+
@queue.save_rerun_command(example.id, rerun_cmd)
|
40
|
+
|
34
41
|
# HACK: try to avoid picking the job we just requeued; we want it
|
35
42
|
# to be picked up by a different worker
|
36
43
|
sleep 0.5
|
@@ -44,7 +51,7 @@ module RSpecQ
|
|
44
51
|
msg = presenter.fully_formatted(nil, @colorizer)
|
45
52
|
msg << "\n"
|
46
53
|
msg << @colorizer.wrap(
|
47
|
-
|
54
|
+
rerun_cmd,
|
48
55
|
RSpec.configuration.failure_color
|
49
56
|
)
|
50
57
|
|
data/lib/rspecq/queue.rb
CHANGED
@@ -135,6 +135,14 @@ module RSpecQ
|
|
135
135
|
)
|
136
136
|
end
|
137
137
|
|
138
|
+
def save_rerun_command(job, cmd)
|
139
|
+
@redis.hset(key("job_metadata"), job, cmd)
|
140
|
+
end
|
141
|
+
|
142
|
+
def rerun_command(job)
|
143
|
+
@redis.hget(key("job_metadata"), job)
|
144
|
+
end
|
145
|
+
|
138
146
|
def record_example_failure(example_id, message)
|
139
147
|
@redis.hset(key_failures, example_id, message)
|
140
148
|
end
|
data/lib/rspecq/reporter.rb
CHANGED
@@ -56,7 +56,7 @@ module RSpecQ
|
|
56
56
|
|
57
57
|
@queue.record_build_time(tests_duration)
|
58
58
|
|
59
|
-
flaky_jobs = @queue.flaky_jobs
|
59
|
+
flaky_jobs = @queue.flaky_jobs.map { |job| @queue.rerun_command(job) }
|
60
60
|
|
61
61
|
puts summary(@queue.example_failures, @queue.non_example_errors,
|
62
62
|
flaky_jobs, humanize_duration(tests_duration))
|
@@ -107,7 +107,12 @@ module RSpecQ
|
|
107
107
|
if !flaky_jobs.empty?
|
108
108
|
summary << "\n\n"
|
109
109
|
summary << "Flaky jobs detected (count=#{flaky_jobs.count}):\n"
|
110
|
-
flaky_jobs.each
|
110
|
+
flaky_jobs.each do |j|
|
111
|
+
summary << RSpec::Core::Formatters::ConsoleCodes.wrap(
|
112
|
+
"#{j}\n",
|
113
|
+
RSpec.configuration.pending_color
|
114
|
+
)
|
115
|
+
end
|
111
116
|
end
|
112
117
|
|
113
118
|
summary
|
data/lib/rspecq/version.rb
CHANGED
data/lib/rspecq/worker.rb
CHANGED
@@ -51,6 +51,9 @@ module RSpecQ
|
|
51
51
|
# Defaults to 30
|
52
52
|
attr_accessor :queue_wait_timeout
|
53
53
|
|
54
|
+
# The RSpec seed
|
55
|
+
attr_accessor :seed
|
56
|
+
|
54
57
|
attr_reader :queue
|
55
58
|
|
56
59
|
def initialize(build_id:, worker_id:, redis_opts:)
|
@@ -64,6 +67,7 @@ module RSpecQ
|
|
64
67
|
@heartbeat_updated_at = nil
|
65
68
|
@max_requeues = 3
|
66
69
|
@queue_wait_timeout = 30
|
70
|
+
@seed = srand && srand % 0xFFFF
|
67
71
|
|
68
72
|
RSpec::Core::Formatters.register(Formatters::JobTimingRecorder, :dump_summary)
|
69
73
|
RSpec::Core::Formatters.register(Formatters::ExampleCountRecorder, :dump_summary)
|
@@ -103,7 +107,7 @@ module RSpecQ
|
|
103
107
|
|
104
108
|
# reconfigure rspec
|
105
109
|
RSpec.configuration.detail_color = :magenta
|
106
|
-
RSpec.configuration.seed =
|
110
|
+
RSpec.configuration.seed = seed
|
107
111
|
RSpec.configuration.backtrace_formatter.filter_gem("rspecq")
|
108
112
|
RSpec.configuration.add_formatter(Formatters::FailureRecorder.new(queue, job, max_requeues))
|
109
113
|
RSpec.configuration.add_formatter(Formatters::ExampleCountRecorder.new(queue))
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspecq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Agis Anastasopoulos
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec-core
|