rspecq 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6b4c91525a2fb29e2198f290877ffe5ef1e753dafe0f9babd75a581e25d7af8
4
- data.tar.gz: 27d3705ee014a5dc77514238b36386eaf11d1bb76601ab25c463796184ea5795
3
+ metadata.gz: 87f2cf8ea2c0b03bf491442902644d24dd001265b2550c0403073d3f34d99903
4
+ data.tar.gz: 646b803ece2861f4ac8faced44f620ea5608636be38033f6931c0550bf4d79bd
5
5
  SHA512:
6
- metadata.gz: 21803fa664abe45f173f7121dc948ebc8dbc0df41046f8e6269e8ec3751b647701b07a8b6a872aad0da22f438c043ebe6bf0fc69bc9c9c8b327e3b157dccab04
7
- data.tar.gz: 4d683884610e2e28ca5ce5cf891e37135886ea4c6ec905f26607c1f0fdd62c1952e9c49983bb0191eb5d42433a800bf88f8227354a213b50645742f21f95af16
6
+ metadata.gz: 418cf064a63ff4ea790495f578bb02f7c76ce6c0536af7a8fbdd8d6a293182f75cc15c587f2bcf798175f1ca0c427a208d8db326d157eacfcc199b783ce00d26
7
+ data.tar.gz: c109a02fc2412f7bb412422d97ee8096d85795893904d7034bbf7928d9c4d8fc5492f279d3f8cfaa77a4065f2ec591ac23915a7d53c181340610c057558fa16f
@@ -4,6 +4,15 @@ Breaking changes are prefixed with a "[BREAKING]" label.
4
4
 
5
5
  ## master (unreleased)
6
6
 
7
+
8
+
9
+ ## 0.2.0 (2020-08-31)
10
+
11
+ ### Added
12
+
13
+ - Flaky jobs are now printed by the reporter in the final build output and also
14
+ emitted to Sentry (if the integration is enabled) [[#26](https://github.com/skroutz/rspecq/pull/26)]
15
+
7
16
  ## 0.1.0 (2020-08-27)
8
17
 
9
18
  ### Added
data/README.md CHANGED
@@ -13,7 +13,7 @@ and [ci-queue](https://github.com/Shopify/ci-queue).
13
13
 
14
14
  ## Features
15
15
 
16
- - Run an RSpec suite among many workers
16
+ - Run an RSpec suite among many workers
17
17
  (potentially located in different hosts) in a distributed fashion,
18
18
  facilitating faster CI builds.
19
19
  - Consolidated, real-time reporting of a build's progress.
@@ -21,11 +21,11 @@ and [ci-queue](https://github.com/Shopify/ci-queue).
21
21
  automatically scheduling slow spec files as individual examples. See
22
22
  [*Spec file splitting*](#spec-file-splitting).
23
23
  - Automatic retry of test failures before being considered legit, in order to
24
- rule out flakiness. See [*Requeues*](#requeues).
24
+ rule out flakiness. Additionally, flaky tests are detected and provided to
25
+ the user. See [*Requeues*](#requeues).
25
26
  - Handles intermittent worker failures (e.g. network hiccups, faulty hardware etc.)
26
27
  by detecting non-responsive workers and requeing their jobs. See [*Worker failures*](#worker-failures)
27
- - [Sentry](https://sentry.io) integration for monitoring important
28
- RSpecQ-level events.
28
+ - Sentry integration for monitoring build-level events. See [*Sentry integration*](#sentry-integration).
29
29
  - [PLANNED] StatsD integration for various build-level metrics and insights.
30
30
  See [#2](https://github.com/skroutz/rspecq/issues/2).
31
31
 
@@ -124,10 +124,13 @@ dynamically (see #3).
124
124
 
125
125
  As a mitigation technique against flaky tests, if an example fails it will be
126
126
  put back to the queue to be picked up by another worker. This will be repeated
127
- up to a certain number of times (set with the `--max-requeues` option), after
128
- which the example will be considered a legit failure and printed as such in the
127
+ up to a certain number of times (set with the `--max-requeues` option), after
128
+ which the example will be considered a legit failure and printed as such in the
129
129
  final report.
130
130
 
131
+ Flaky tests are also detected and printed as such in the final report. They are
132
+ also emitted to Sentry (see [Sentry integration](#sentry-integration)).
133
+
131
134
  ### Worker failures
132
135
 
133
136
  It's not uncommon for CI processes to encounter unrecoverable failures for
@@ -173,8 +176,8 @@ rejects).
173
176
  The downside of this design is that it's more complicated, since the scheduling
174
177
  of spec files happens based on timings calculated from previous runs. This
175
178
  means that RSpecQ maintains a key with the timing of each job and updates it
176
- on every run (if the `--timings` option was used). Also, RSpecQ has a "slow
177
- file threshold" which, currently has to be set manually (but this can be
179
+ on every run (if the `--update-timings` option was used). Also, RSpecQ has a
180
+ "slow file threshold" which, currently has to be set manually (but this can be
178
181
  improved in the future).
179
182
 
180
183
 
@@ -184,6 +184,7 @@ module RSpecQ
184
184
  @redis.hgetall(key_errors)
185
185
  end
186
186
 
187
+ # True if the build is complete, false otherwise
187
188
  def exhausted?
188
189
  return false if !published?
189
190
 
@@ -216,6 +217,19 @@ module RSpecQ
216
217
  @redis.lrange(key_queue_unprocessed, 0, -1)
217
218
  end
218
219
 
220
+ # Returns the jobs considered flaky (i.e. initially failed but passed
221
+ # after being retried). Must be called after the build is complete,
222
+ # otherwise an exception will be raised.
223
+ def flaky_jobs
224
+ raise "Queue is not yet exhausted" if !exhausted?
225
+
226
+ requeued = @redis.hkeys(key_requeues)
227
+
228
+ return [] if requeued.empty?
229
+
230
+ requeued - @redis.hkeys(key_failures)
231
+ end
232
+
219
233
  # redis: STRING [STATUS_INITIALIZING, STATUS_READY]
220
234
  def key_queue_status
221
235
  key("queue", "status")
@@ -45,8 +45,13 @@ module RSpecQ
45
45
  raise "Build not finished after #{@timeout} seconds" if !finished
46
46
 
47
47
  @queue.record_build_time(tests_duration)
48
+
49
+ flaky_jobs = @queue.flaky_jobs
50
+
48
51
  puts summary(@queue.example_failures, @queue.non_example_errors,
49
- humanize_duration(tests_duration))
52
+ flaky_jobs, humanize_duration(tests_duration))
53
+
54
+ flaky_jobs_to_sentry(flaky_jobs, tests_duration)
50
55
 
51
56
  exit 1 if !@queue.build_successful?
52
57
  end
@@ -60,7 +65,7 @@ module RSpecQ
60
65
  end
61
66
 
62
67
  # We try to keep this output consistent with RSpec's original output
63
- def summary(failures, errors, duration)
68
+ def summary(failures, errors, flaky_jobs, duration)
64
69
  failed_examples_section = "\nFailed examples:\n\n"
65
70
 
66
71
  failures.each do |_job, msg|
@@ -81,6 +86,14 @@ module RSpecQ
81
86
  "#{errors.count} errors"
82
87
  summary << "\n\n"
83
88
  summary << "Spec execution time: #{duration}"
89
+
90
+ if !flaky_jobs.empty?
91
+ summary << "\n\n"
92
+ summary << "Flaky jobs detected (count=#{flaky_jobs.count}):\n"
93
+ flaky_jobs.each { |j| summary << " #{j}\n" }
94
+ end
95
+
96
+ summary
84
97
  end
85
98
 
86
99
  def failure_formatted(rspec_output)
@@ -90,5 +103,20 @@ module RSpecQ
90
103
  def humanize_duration(seconds)
91
104
  Time.at(seconds).utc.strftime("%H:%M:%S")
92
105
  end
106
+
107
+ def flaky_jobs_to_sentry(jobs, build_duration)
108
+ return if jobs.empty?
109
+
110
+ Raven.capture_message("Flaky jobs detected", level: "warning", extra: {
111
+ build: @build_id,
112
+ build_timeout: @timeout,
113
+ queue: @queue.inspect,
114
+ object: self.inspect,
115
+ pid: Process.pid,
116
+ flaky_jobs: jobs,
117
+ flaky_jobs_count: jobs.count,
118
+ build_duration: build_duration
119
+ })
120
+ end
93
121
  end
94
122
  end
@@ -1,3 +1,3 @@
1
1
  module RSpecQ
2
- VERSION = "0.1.0".freeze
2
+ VERSION = "0.2.0".freeze
3
3
  end
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.1.0
4
+ version: 0.2.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: 2020-08-27 00:00:00.000000000 Z
11
+ date: 2020-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec-core
@@ -148,7 +148,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
148
  - !ruby/object:Gem::Version
149
149
  version: '0'
150
150
  requirements: []
151
- rubygems_version: 3.1.4
151
+ rubyforge_project:
152
+ rubygems_version: 2.7.6.2
152
153
  signing_key:
153
154
  specification_version: 4
154
155
  summary: Optimally distribute and run RSpec suites among parallel workers; for faster