ci-queue 0.20.0 → 0.20.5
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 +4 -2
- data/ci-queue.gemspec +1 -1
- data/lib/ci/queue/redis/worker.rb +12 -4
- data/lib/ci/queue/version.rb +1 -1
- data/lib/minitest/queue.rb +42 -0
- data/lib/minitest/queue/error_report.rb +4 -0
- data/lib/minitest/queue/failure_formatter.rb +1 -0
- data/lib/minitest/queue/junit_reporter.rb +22 -23
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b3b09a46db2e51a46c56d7621c04519733ae879c654fb1f40b501ee83ccc18e
|
4
|
+
data.tar.gz: ce5611bebdb7d779a4d4cc9ed5c647445b1f1e11f684739e50d723dc62c9b724
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ae21355372fd174e00228a23c52ac09dafd7660f0931178602e96ae1b0c38f50d7a931f16781190e8de90b5fcc26715b518c87ff94d75923e26b736eeca6b8a
|
7
|
+
data.tar.gz: 302a5dc245808eda350733554e87b176e9e5b949a041c09adf3da3dfb119d1cac9e4af7301952aeebc96280c896bb6bb4f7abfc48cf83739cb970a1eaa8d4189
|
data/README.md
CHANGED
@@ -51,7 +51,9 @@ The runner also comes with a tool to investigate leaky tests:
|
|
51
51
|
minitest-queue --queue path/to/test_order.log --failing-test 'SomeTest#test_something' bisect -Itest test/**/*_test.rb
|
52
52
|
```
|
53
53
|
|
54
|
-
### RSpec
|
54
|
+
### RSpec [DEPRECATED]
|
55
|
+
|
56
|
+
The rspec-queue runner is deprecated. The minitest-queue runner continues to be supported and is actively being improved. At Shopify, we strongly recommend that new projects set up their test suite using Minitest rather than RSpec.
|
55
57
|
|
56
58
|
Assuming you use one of the supported CI providers, the command can be as simple as:
|
57
59
|
|
@@ -67,4 +69,4 @@ rspec-queue --queue redis://example.com --timeout 600 --report
|
|
67
69
|
|
68
70
|
#### Limitations
|
69
71
|
|
70
|
-
Because of how `ci-queue`
|
72
|
+
Because of how `ci-queue` executes the examples, `before(:all)` and `after(:all)` hooks are not supported. `rspec-queue` will explicitly reject them.
|
data/ci-queue.gemspec
CHANGED
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_development_dependency 'rake'
|
34
34
|
spec.add_development_dependency 'minitest', ENV.fetch('MINITEST_VERSION', '~> 5.11')
|
35
35
|
spec.add_development_dependency 'rspec', '~> 3.7.0'
|
36
|
-
spec.add_development_dependency 'redis'
|
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'
|
39
39
|
|
@@ -56,10 +56,18 @@ module CI
|
|
56
56
|
rescue *CONNECTION_ERRORS
|
57
57
|
end
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
59
|
+
if ::Redis.method_defined?(:exists?)
|
60
|
+
def retrying?
|
61
|
+
redis.exists?(key('worker', worker_id, 'queue'))
|
62
|
+
rescue *CONNECTION_ERRORS
|
63
|
+
false
|
64
|
+
end
|
65
|
+
else
|
66
|
+
def retrying?
|
67
|
+
redis.exists(key('worker', worker_id, 'queue'))
|
68
|
+
rescue *CONNECTION_ERRORS
|
69
|
+
false
|
70
|
+
end
|
63
71
|
end
|
64
72
|
|
65
73
|
def retry_queue
|
data/lib/ci/queue/version.rb
CHANGED
data/lib/minitest/queue.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'shellwords'
|
2
3
|
require 'minitest'
|
3
4
|
require 'minitest/reporters'
|
4
5
|
|
@@ -102,6 +103,47 @@ module Minitest
|
|
102
103
|
end
|
103
104
|
|
104
105
|
module Queue
|
106
|
+
attr_writer :run_command_formatter, :project_root
|
107
|
+
|
108
|
+
def run_command_formatter
|
109
|
+
@run_command_formatter ||= if defined?(Rails) && defined?(Rails::TestUnitRailtie)
|
110
|
+
RAILS_RUN_COMMAND_FORMATTER
|
111
|
+
else
|
112
|
+
DEFAULT_RUN_COMMAND_FORMATTER
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
DEFAULT_RUN_COMMAND_FORMATTER = lambda do |runnable|
|
117
|
+
filename = Minitest::Queue.relative_path(runnable.source_location[0])
|
118
|
+
identifier = "#{runnable.klass}##{runnable.name}"
|
119
|
+
['bundle', 'exec', 'ruby', '-Ilib:test', filename, '-n', identifier]
|
120
|
+
end
|
121
|
+
|
122
|
+
RAILS_RUN_COMMAND_FORMATTER = lambda do |runnable|
|
123
|
+
filename = Minitest::Queue.relative_path(runnable.source_location[0])
|
124
|
+
lineno = runnable.source_location[1]
|
125
|
+
['bin/rails', 'test', "#{filename}:#{lineno}"]
|
126
|
+
end
|
127
|
+
|
128
|
+
def run_command_for_runnable(runnable)
|
129
|
+
command = run_command_formatter.call(runnable)
|
130
|
+
if command.is_a?(Array)
|
131
|
+
Shellwords.join(command)
|
132
|
+
else
|
133
|
+
command
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.project_root
|
138
|
+
@project_root ||= Dir.pwd
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.relative_path(path, root: project_root)
|
142
|
+
Pathname(path).relative_path_from(Pathname(root)).to_s
|
143
|
+
rescue ArgumentError
|
144
|
+
path
|
145
|
+
end
|
146
|
+
|
105
147
|
class SingleExample
|
106
148
|
|
107
149
|
def initialize(runnable, method_name)
|
@@ -16,7 +16,12 @@ module Minitest
|
|
16
16
|
def generate_document
|
17
17
|
suites = tests.group_by { |test| test.klass }
|
18
18
|
|
19
|
-
doc = REXML::Document.new
|
19
|
+
doc = REXML::Document.new(nil, {
|
20
|
+
:prologue_quote => :quote,
|
21
|
+
:attribute_quote => :quote,
|
22
|
+
})
|
23
|
+
doc << REXML::XMLDecl.new('1.1', 'utf-8')
|
24
|
+
|
20
25
|
testsuites = doc.add_element('testsuites')
|
21
26
|
suites.each do |suite, tests|
|
22
27
|
add_tests_to(testsuites, suite, tests)
|
@@ -25,7 +30,6 @@ module Minitest
|
|
25
30
|
end
|
26
31
|
|
27
32
|
def format_document(doc, io)
|
28
|
-
io << "<?xml version='1.0' encoding='UTF-8'?>\n"
|
29
33
|
formatter = REXML::Formatters::Pretty.new
|
30
34
|
formatter.write(doc, io)
|
31
35
|
io << "\n"
|
@@ -44,17 +48,7 @@ module Minitest
|
|
44
48
|
|
45
49
|
def add_tests_to(testsuites, suite, tests)
|
46
50
|
suite_result = analyze_suite(tests)
|
47
|
-
relative_path =
|
48
|
-
Pathname.new('')
|
49
|
-
else
|
50
|
-
file_path = Pathname.new(tests.first.source_location.first)
|
51
|
-
if file_path.relative?
|
52
|
-
file_path
|
53
|
-
else
|
54
|
-
base_path = Pathname.new(@base_path)
|
55
|
-
file_path.relative_path_from(base_path)
|
56
|
-
end
|
57
|
-
end
|
51
|
+
relative_path = location_for_runnable(tests.first) || '<unknown>'
|
58
52
|
|
59
53
|
testsuite = testsuites.add_element(
|
60
54
|
'testsuite',
|
@@ -75,7 +69,8 @@ module Minitest
|
|
75
69
|
'classname' => suite,
|
76
70
|
'assertions' => test.assertions,
|
77
71
|
'time' => test.time,
|
78
|
-
'flaky_test' => test.flaked
|
72
|
+
'flaky_test' => test.flaked?,
|
73
|
+
'run-command' => Minitest.run_command_for_runnable(test),
|
79
74
|
}
|
80
75
|
attributes['lineno'] = lineno if lineno != -1
|
81
76
|
|
@@ -101,29 +96,33 @@ module Minitest
|
|
101
96
|
message.lines.first.chomp.gsub(/\e\[[^m]+m/, '')
|
102
97
|
end
|
103
98
|
|
99
|
+
def project_root_path_matcher
|
100
|
+
@project_root_path_matcher ||= %r{(?<=\s)#{Regexp.escape(Minitest::Queue.project_root)}/}
|
101
|
+
end
|
102
|
+
|
104
103
|
def message_for(test)
|
105
104
|
suite = test.klass
|
106
105
|
name = test.name
|
107
106
|
error = test.failure
|
108
107
|
|
108
|
+
message_with_relative_paths = error.message.gsub(project_root_path_matcher, '')
|
109
109
|
if test.passed?
|
110
110
|
nil
|
111
111
|
elsif test.skipped?
|
112
|
-
"\nSkipped:\n#{name}(#{suite}) [#{
|
112
|
+
"\nSkipped:\n#{name}(#{suite}) [#{location_for_runnable(test)}]:\n#{message_with_relative_paths}\n"
|
113
113
|
elsif test.failure
|
114
|
-
"\nFailure:\n#{name}(#{suite}) [#{
|
114
|
+
"\nFailure:\n#{name}(#{suite}) [#{location_for_runnable(test)}]:\n#{message_with_relative_paths}\n"
|
115
115
|
elsif test.error?
|
116
|
-
"\nError:\n#{name}(#{suite}) [#{
|
116
|
+
"\nError:\n#{name}(#{suite}) [#{location_for_runnable(test)}]:\n#{message_with_relative_paths}\n"
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
|
-
def
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
120
|
+
def location_for_runnable(runnable)
|
121
|
+
if runnable.source_location.first == 'unknown'
|
122
|
+
nil
|
123
|
+
else
|
124
|
+
Minitest::Queue.relative_path(runnable.source_location.first)
|
125
125
|
end
|
126
|
-
last_before_assertion.sub(/:in .*$/, '')
|
127
126
|
end
|
128
127
|
|
129
128
|
def analyze_suite(tests)
|
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.20.
|
4
|
+
version: 0.20.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Boussier
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -70,16 +70,16 @@ dependencies:
|
|
70
70
|
name: redis
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: simplecov
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|