rspecq 0.5.0 → 0.6.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/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
|