ci-queue 0.78.0 → 0.79.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/Gemfile.lock +1 -1
- data/lib/ci/queue/version.rb +1 -1
- data/lib/minitest/queue/build_status_reporter.rb +35 -1
- data/lib/rspec/queue/build_status_recorder.rb +8 -7
- data/lib/rspec/queue/error_report.rb +92 -0
- data/lib/rspec/queue/failure_formatter.rb +45 -0
- data/lib/rspec/queue.rb +88 -4
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a6bc964bea9e748549dc7e57a2ec4c0207e080fa5d644fac6d75165b88b44cf
|
4
|
+
data.tar.gz: 22acfa15e29f811514aea54861ae9f4c422e11d42eadbed7241b030f5a3ed79f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 02b7be5eea0c4f50eacd9caa19bb64f7ab52720deb92897573efad680bf1130aa717f09302b3c6573bd0c7e5eed592ba3acb601cfeb8a2eabbdc9cb422826d2e
|
7
|
+
data.tar.gz: dbdca360f7eba2da549559f982c73175302dc5e92f414972f39c8a6fb77de9a95d3dfc783bae4be3a63dcefa2844c69e5fae3842f828dff42d66a2b9058aae64
|
data/Gemfile.lock
CHANGED
data/lib/ci/queue/version.rb
CHANGED
@@ -153,7 +153,10 @@ module Minitest
|
|
153
153
|
puts
|
154
154
|
|
155
155
|
errors = error_reports
|
156
|
-
|
156
|
+
if errors.any?
|
157
|
+
pretty_print_summary(errors)
|
158
|
+
pretty_print_failures(errors)
|
159
|
+
end
|
157
160
|
|
158
161
|
build.worker_errors.to_a.sort.each do |worker_id, error|
|
159
162
|
puts red("Worker #{worker_id } crashed")
|
@@ -224,6 +227,37 @@ module Minitest
|
|
224
227
|
|
225
228
|
attr_reader :build, :supervisor
|
226
229
|
|
230
|
+
def pretty_print_summary(errors)
|
231
|
+
test_paths = errors.map(&:test_file).compact
|
232
|
+
return unless test_paths.any?
|
233
|
+
|
234
|
+
file_counts = test_paths.each_with_object(Hash.new(0)) { |path, counts| counts[path] += 1 }
|
235
|
+
|
236
|
+
puts "\n" + "=" * 80
|
237
|
+
puts "FAILED TESTS SUMMARY:"
|
238
|
+
puts "=" * 80
|
239
|
+
file_counts.sort_by { |path, _| path }.each do |path, count|
|
240
|
+
relative_path = Minitest::Queue.relative_path(path)
|
241
|
+
if count == 1
|
242
|
+
puts " #{relative_path}"
|
243
|
+
else
|
244
|
+
puts " #{relative_path} (#{count} failures)"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
puts "=" * 80
|
248
|
+
end
|
249
|
+
|
250
|
+
def pretty_print_failures(errors)
|
251
|
+
errors.each_with_index do |error, index|
|
252
|
+
puts "\n" + "-" * 80
|
253
|
+
puts "Error #{index + 1} of #{errors.size}"
|
254
|
+
puts "-" * 80
|
255
|
+
puts error
|
256
|
+
end
|
257
|
+
|
258
|
+
puts "=" * 80
|
259
|
+
end
|
260
|
+
|
227
261
|
def timed_out?
|
228
262
|
supervisor.time_left.to_i <= 0
|
229
263
|
end
|
@@ -1,4 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'rspec/queue/failure_formatter'
|
3
|
+
require 'rspec/queue/error_report'
|
4
|
+
|
2
5
|
module RSpec
|
3
6
|
module Queue
|
4
7
|
class BuildStatusRecorder
|
@@ -6,7 +9,9 @@ module RSpec
|
|
6
9
|
|
7
10
|
class << self
|
8
11
|
attr_accessor :build
|
12
|
+
attr_accessor :failure_formatter
|
9
13
|
end
|
14
|
+
self.failure_formatter = FailureFormatter
|
10
15
|
|
11
16
|
def initialize(*)
|
12
17
|
end
|
@@ -18,17 +23,13 @@ module RSpec
|
|
18
23
|
|
19
24
|
def example_failed(notification)
|
20
25
|
example = notification.example
|
21
|
-
build.record_error(example.id,
|
22
|
-
notification.fully_formatted(nil),
|
23
|
-
colorized_rerun_command(example),
|
24
|
-
].join("\n"))
|
26
|
+
build.record_error(example.id, dump(notification))
|
25
27
|
end
|
26
28
|
|
27
29
|
private
|
28
30
|
|
29
|
-
def
|
30
|
-
|
31
|
-
colorizer.wrap("# #{example.full_description}", RSpec.configuration.detail_color)
|
31
|
+
def dump(notification)
|
32
|
+
ErrorReport.new(self.class.failure_formatter.new(notification).to_h).dump
|
32
33
|
end
|
33
34
|
|
34
35
|
def build
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module RSpec
|
3
|
+
module Queue
|
4
|
+
class ErrorReport
|
5
|
+
class << self
|
6
|
+
attr_accessor :coder
|
7
|
+
|
8
|
+
def load(payload)
|
9
|
+
new(coder.load(payload))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Default to Marshal
|
14
|
+
self.coder = Marshal
|
15
|
+
|
16
|
+
# Try to use SnappyPack if available from consumer's bundle
|
17
|
+
begin
|
18
|
+
require 'snappy'
|
19
|
+
require 'msgpack'
|
20
|
+
require 'stringio'
|
21
|
+
|
22
|
+
module SnappyPack
|
23
|
+
extend self
|
24
|
+
|
25
|
+
MSGPACK = MessagePack::Factory.new
|
26
|
+
MSGPACK.register_type(0x00, Symbol)
|
27
|
+
|
28
|
+
def load(payload)
|
29
|
+
io = StringIO.new(Snappy.inflate(payload))
|
30
|
+
MSGPACK.unpacker(io).unpack
|
31
|
+
end
|
32
|
+
|
33
|
+
def dump(object)
|
34
|
+
io = StringIO.new
|
35
|
+
packer = MSGPACK.packer(io)
|
36
|
+
packer.pack(object)
|
37
|
+
packer.flush
|
38
|
+
io.rewind
|
39
|
+
Snappy.deflate(io.string).force_encoding(Encoding::UTF_8)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
self.coder = SnappyPack
|
44
|
+
rescue LoadError
|
45
|
+
end
|
46
|
+
|
47
|
+
def initialize(data)
|
48
|
+
@data = data
|
49
|
+
end
|
50
|
+
|
51
|
+
def dump
|
52
|
+
self.class.coder.dump(@data)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_name
|
56
|
+
@data[:test_name]
|
57
|
+
end
|
58
|
+
|
59
|
+
def error_class
|
60
|
+
@data[:error_class]
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_and_module_name
|
64
|
+
@data[:test_and_module_name]
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_suite
|
68
|
+
@data[:test_suite]
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_file
|
72
|
+
@data[:test_file]
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_line
|
76
|
+
@data[:test_line]
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_h
|
80
|
+
@data
|
81
|
+
end
|
82
|
+
|
83
|
+
def to_s
|
84
|
+
output
|
85
|
+
end
|
86
|
+
|
87
|
+
def output
|
88
|
+
@data[:output]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'delegate'
|
3
|
+
require 'ci/queue/output_helpers'
|
4
|
+
|
5
|
+
module RSpec
|
6
|
+
module Queue
|
7
|
+
class FailureFormatter < SimpleDelegator
|
8
|
+
include ::CI::Queue::OutputHelpers
|
9
|
+
|
10
|
+
def initialize(notification)
|
11
|
+
@notification = notification
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
[
|
17
|
+
@notification.fully_formatted(nil),
|
18
|
+
colorized_rerun_command(@notification.example)
|
19
|
+
].join("\n")
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_h
|
23
|
+
example = @notification.example
|
24
|
+
{
|
25
|
+
test_file: example.file_path,
|
26
|
+
test_line: example.metadata[:line_number],
|
27
|
+
test_and_module_name: example.id,
|
28
|
+
test_name: example.description,
|
29
|
+
test_suite: example.example_group.description,
|
30
|
+
error_class: @notification.exception.class.name,
|
31
|
+
output: to_s,
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_reader :notification
|
38
|
+
|
39
|
+
def colorized_rerun_command(example, colorizer=::RSpec::Core::Formatters::ConsoleCodes)
|
40
|
+
colorizer.wrap("rspec #{example.location_rerun_argument}", RSpec.configuration.failure_color) + " " +
|
41
|
+
colorizer.wrap("# #{example.full_description}", RSpec.configuration.detail_color)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/rspec/queue.rb
CHANGED
@@ -5,6 +5,7 @@ require 'rspec/core'
|
|
5
5
|
require 'ci/queue'
|
6
6
|
require 'rspec/queue/build_status_recorder'
|
7
7
|
require 'rspec/queue/order_recorder'
|
8
|
+
require 'rspec/queue/error_report'
|
8
9
|
|
9
10
|
module RSpec
|
10
11
|
module Queue
|
@@ -291,16 +292,56 @@ module RSpec
|
|
291
292
|
end
|
292
293
|
end
|
293
294
|
|
294
|
-
|
295
|
-
|
295
|
+
errors = supervisor.build.error_reports.sort_by(&:first).map do |_, error_data|
|
296
|
+
RSpec::Queue::ErrorReport.load(error_data)
|
297
|
+
end
|
296
298
|
if errors.empty?
|
297
299
|
step(green('No errors found'))
|
298
300
|
0
|
299
301
|
else
|
300
302
|
message = errors.size == 1 ? "1 error found" : "#{errors.size} errors found"
|
301
303
|
step(red(message), collapsed: false)
|
302
|
-
|
304
|
+
|
305
|
+
pretty_print_summary(errors)
|
306
|
+
pretty_print_failures(errors)
|
303
307
|
1
|
308
|
+
# Example output
|
309
|
+
#
|
310
|
+
# FAILED TESTS SUMMARY:
|
311
|
+
# =================================================================================
|
312
|
+
# ./spec/dummy_spec.rb
|
313
|
+
# ./spec/dummy_spec_2.rb (2 failures)
|
314
|
+
# ./spec/dummy_spec_3.rb (3 failures)
|
315
|
+
# =================================================================================
|
316
|
+
#
|
317
|
+
# --------------------------------------------------------------------------------
|
318
|
+
# Error 1 of 3
|
319
|
+
# --------------------------------------------------------------------------------
|
320
|
+
#
|
321
|
+
# Object doesn't work on first try
|
322
|
+
# Failure/Error: expect(1 + 1).to be == 42
|
323
|
+
#
|
324
|
+
# expected: == 42
|
325
|
+
# got: 2
|
326
|
+
#
|
327
|
+
# --- stacktrace will be here ---
|
328
|
+
# --- rerun command will be here ---
|
329
|
+
#
|
330
|
+
# --------------------------------------------------------------------------------
|
331
|
+
# Error 2 of 3
|
332
|
+
# --------------------------------------------------------------------------------
|
333
|
+
#
|
334
|
+
# Object doesn't work on first try
|
335
|
+
# Failure/Error: expect(1 + 1).to be == 42
|
336
|
+
#
|
337
|
+
# expected: == 42
|
338
|
+
# got: 2
|
339
|
+
#
|
340
|
+
# --- stacktrace will be here ---
|
341
|
+
# --- rerun command will be here ---
|
342
|
+
#
|
343
|
+
# ... etc
|
344
|
+
# =================================================================================
|
304
345
|
end
|
305
346
|
end
|
306
347
|
|
@@ -320,6 +361,38 @@ module RSpec
|
|
320
361
|
invalid_usage!('Missing --queue parameter') unless queue_url
|
321
362
|
invalid_usage!('Missing --build parameter') unless RSpec::Queue.config.build_id
|
322
363
|
end
|
364
|
+
|
365
|
+
private
|
366
|
+
|
367
|
+
def pretty_print_summary(errors)
|
368
|
+
test_paths = errors.map(&:test_file).compact
|
369
|
+
return unless test_paths.any?
|
370
|
+
|
371
|
+
file_counts = test_paths.each_with_object(Hash.new(0)) { |path, counts| counts[path] += 1 }
|
372
|
+
|
373
|
+
puts "\n" + "=" * 80
|
374
|
+
puts "FAILED TESTS SUMMARY:"
|
375
|
+
puts "=" * 80
|
376
|
+
file_counts.sort_by { |path, _| path }.each do |path, count|
|
377
|
+
if count == 1
|
378
|
+
puts " #{path}"
|
379
|
+
else
|
380
|
+
puts " #{path} (#{count} failures)"
|
381
|
+
end
|
382
|
+
end
|
383
|
+
puts "=" * 80
|
384
|
+
end
|
385
|
+
|
386
|
+
def pretty_print_failures(errors)
|
387
|
+
errors.each_with_index do |error, index|
|
388
|
+
puts "\n" + "-" * 80
|
389
|
+
puts "Error #{index + 1} of #{errors.size}"
|
390
|
+
puts "-" * 80
|
391
|
+
puts error.to_s
|
392
|
+
end
|
393
|
+
|
394
|
+
puts "=" * 80
|
395
|
+
end
|
323
396
|
end
|
324
397
|
|
325
398
|
class QueueReporter < SimpleDelegator
|
@@ -362,7 +435,18 @@ module RSpec
|
|
362
435
|
invalid_usage!('Missing --queue parameter') unless queue_url
|
363
436
|
invalid_usage!('Missing --build parameter') unless RSpec::Queue.config.build_id
|
364
437
|
invalid_usage!('Missing --worker parameter') unless RSpec::Queue.config.worker_id
|
365
|
-
RSpec.
|
438
|
+
RSpec.configure do |config|
|
439
|
+
config.backtrace_exclusion_patterns = [
|
440
|
+
# Filter bundler paths
|
441
|
+
%r{/tmp/bundle/},
|
442
|
+
# RSpec internals
|
443
|
+
%r{/gems/rspec-},
|
444
|
+
# ci-queue and rspec-queue internals
|
445
|
+
%r{exe/rspec-queue},
|
446
|
+
%r{lib/ci/queue/},
|
447
|
+
%r{rspec/queue}
|
448
|
+
]
|
449
|
+
end
|
366
450
|
end
|
367
451
|
|
368
452
|
def run_specs(example_groups)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ci-queue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.79.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Boussier
|
@@ -234,6 +234,8 @@ files:
|
|
234
234
|
- lib/minitest/reporters/statsd_reporter.rb
|
235
235
|
- lib/rspec/queue.rb
|
236
236
|
- lib/rspec/queue/build_status_recorder.rb
|
237
|
+
- lib/rspec/queue/error_report.rb
|
238
|
+
- lib/rspec/queue/failure_formatter.rb
|
237
239
|
- lib/rspec/queue/order_recorder.rb
|
238
240
|
homepage: https://github.com/Shopify/ci-queue
|
239
241
|
licenses:
|