ci-queue 0.20.0 → 0.20.5

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: 020e4e1012b0be90bc94deac97a2fb6e00a11aeed0c35e1cffba506145f0b2aa
4
- data.tar.gz: 86a96759c23bacf51457b1a24c0284e40dba6904e16ac6a8bc52fdf83fd4243e
3
+ metadata.gz: 8b3b09a46db2e51a46c56d7621c04519733ae879c654fb1f40b501ee83ccc18e
4
+ data.tar.gz: ce5611bebdb7d779a4d4cc9ed5c647445b1f1e11f684739e50d723dc62c9b724
5
5
  SHA512:
6
- metadata.gz: a77b0ee4af5f570ef8a398377049afdd88ce611ac9c16319decb9b627c265ef7f2efa773317e9ae04a5472d88d595471e2384fc7bfd4778c291c59d8fa79a08b
7
- data.tar.gz: ba72651f0072f98167131617a2635b05260d343108ac4d073a5dba56bcb9e5f7980b14abe66ac10d88662967a86b8cd682d549cf8a22f37dad3b5ea94aa82018
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` execute the examples, `before(:all)` and `after(:all)` hooks are not supported. `rspec-queue` will explicitly reject them.
72
+ Because of how `ci-queue` executes the examples, `before(:all)` and `after(:all)` hooks are not supported. `rspec-queue` will explicitly reject them.
@@ -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', '~> 3.3'
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
- def retrying?
60
- redis.exists(key('worker', worker_id, 'queue'))
61
- rescue *CONNECTION_ERRORS
62
- false
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
@@ -2,7 +2,7 @@
2
2
 
3
3
  module CI
4
4
  module Queue
5
- VERSION = '0.20.0'
5
+ VERSION = '0.20.5'
6
6
  DEV_SCRIPTS_ROOT = ::File.expand_path('../../../../../redis', __FILE__)
7
7
  RELEASE_SCRIPTS_ROOT = ::File.expand_path('../redis', __FILE__)
8
8
  end
@@ -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)
@@ -58,6 +58,10 @@ module Minitest
58
58
  @data[:test_and_module_name]
59
59
  end
60
60
 
61
+ def test_suite
62
+ @data[:test_suite]
63
+ end
64
+
61
65
  def test_file
62
66
  @data[:test_file]
63
67
  end
@@ -27,6 +27,7 @@ module Minitest
27
27
  test_line: test_line,
28
28
  test_and_module_name: "#{test.klass}##{test.name}",
29
29
  test_name: test.name,
30
+ test_suite: test.klass,
30
31
  error_class: test.failure.exception.class.name,
31
32
  output: to_s,
32
33
  }
@@ -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 = if tests.first.source_location.first == 'unknown'
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}) [#{location(error)}]:\n#{error.message}\n"
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}) [#{location(error)}]:\n#{error.message}\n"
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}) [#{location(error)}]:\n#{error.message}\n"
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 location(exception)
121
- last_before_assertion = ''
122
- (exception.backtrace || []).reverse_each do |s|
123
- break if s =~ /in .(assert|refute|flunk|pass|fail|raise|must|wont)/
124
- last_before_assertion = s
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.0
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-05-07 00:00:00.000000000 Z
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: '3.3'
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: '3.3'
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: simplecov
85
85
  requirement: !ruby/object:Gem::Requirement