knapsack_pro 8.4.0 → 9.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 17dceae7090394f68959e5b8bdef4c0640ce4027b28efe41fb8f3d612b5f0348
4
- data.tar.gz: 5828288a2160348d9acce467e17d16da00e8f794aa39e70d0d0b5fecc0b9188c
3
+ metadata.gz: 3f83ec80d7b3dcbd9415335f5f340e48908fbeaeee13e92203cb78df1232f82e
4
+ data.tar.gz: 19c08fe18b1555fd1a5d218b32d8baf1534e9cc87b63fc9d17d1c7ddb0129f46
5
5
  SHA512:
6
- metadata.gz: abf9abe76b5e0841d95c09230cd88289e6c197a26dad27cd2a9c7f2fe97310c9d1fbe1ddb77134676c604daa7a28bd8d6c405598262f9623a9110c5b7ce15751
7
- data.tar.gz: 7c9a0f978b8f01b2e5ad888535ddfbaf006b20da5a5853edc454dd82044f1608b2ce9d21acd25a00c77146bbad7e0954d76f5fc2ae541970cdfd9feaee0bc45e
6
+ metadata.gz: d00064e828c1a90a3f2001cbbbee5086f7ac565b6f6ffe015237b6cab12bbdcc48a6a6199f615aaf1ff73ec4bdf4c666c84df44a8e6bc792e4d33387f4c55d71
7
+ data.tar.gz: b5dd5757440d7e38a54a44c69fe0c650185ade87dc00b00ebf24242fb637e3a062cdb45b7b85e39eae28547cd8513ad888aa8c6488a3734750a44530c64b6596
data/.circleci/config.yml CHANGED
@@ -291,7 +291,7 @@ jobs:
291
291
  working_directory: ~/rails-app-with-knapsack_pro
292
292
  command: |
293
293
  # split by test examples AND a single CI node ||
294
- export KNAPSACK_PRO_BRANCH="$CIRCLE_BRANCH--$CIRCLE_BUILD_NUM--queue--split--single-node"
294
+ export KNAPSACK_PRO_BRANCH="$CIRCLE_BRANCH--$CIRCLE_BUILD_NUM--queue--split--single-node--$CIRCLE_NODE_INDEX"
295
295
  export KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true
296
296
  export KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES=true
297
297
  export KNAPSACK_PRO_CI_NODE_TOTAL=1
data/CHANGELOG.md CHANGED
@@ -1,6 +1,19 @@
1
1
  # Changelog
2
2
 
3
- ### UNRELEASED (patch)
3
+ ### 9.0.0
4
+
5
+ * __(breaking change)__ Require Ruby >=3.0.0
6
+ * Implement IP rotation for Ruby <3.4 to mitigate connection errors
7
+ * Upon connection failure, log additional diagnostics to gather more context
8
+ * Change log format from `LEVEL -- : [knapsack_pro] ...` to `ERROR -- knapsack_pro: ...`
9
+
10
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/313
11
+
12
+ * GitHub Actions: Detect either head branch in Pull Requests or short ref name (vs fully-formed ref) in the other cases
13
+
14
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/308
15
+
16
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v8.4.0...v9.0.0
4
17
 
5
18
  ### 8.4.0
6
19
 
data/knapsack_pro.gemspec CHANGED
@@ -6,7 +6,7 @@ require 'knapsack_pro/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'knapsack_pro'
8
8
  spec.version = KnapsackPro::VERSION
9
- spec.required_ruby_version = '>= 2.7.0'
9
+ spec.required_ruby_version = '>= 3.0.0'
10
10
  spec.authors = ['ArturT']
11
11
  spec.email = ['support@knapsackpro.com']
12
12
  spec.summary = %q{Knapsack Pro splits tests across parallel CI nodes and ensures each parallel job finish work at a similar time.}
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'stringio'
4
+
3
5
  module KnapsackPro
4
6
  module Client
5
7
  class Connection
@@ -10,6 +12,7 @@ module KnapsackPro
10
12
 
11
13
  def initialize(action)
12
14
  @action = action
15
+ @http_debug_output = StringIO.new
13
16
  end
14
17
 
15
18
  def call
@@ -17,7 +20,7 @@ module KnapsackPro
17
20
  end
18
21
 
19
22
  def success?
20
- return false if !response_body
23
+ return false unless response_body
21
24
 
22
25
  status = http_response.code.to_i
23
26
  status >= 200 && status < 500
@@ -29,6 +32,7 @@ module KnapsackPro
29
32
 
30
33
  def api_code
31
34
  return unless response_body
35
+
32
36
  response_body['code']
33
37
  end
34
38
 
@@ -45,20 +49,8 @@ module KnapsackPro
45
49
  KnapsackPro.logger
46
50
  end
47
51
 
48
- def endpoint
49
- KnapsackPro::Config::Env.endpoint
50
- end
51
-
52
- def endpoint_url
53
- endpoint + action.endpoint_path
54
- end
55
-
56
- def request_hash
57
- action.request_hash
58
- end
59
-
60
- def request_body
61
- request_hash.to_json
52
+ def endpoint_uri
53
+ URI.parse(KnapsackPro::Config::Env.endpoint + action.endpoint_path)
62
54
  end
63
55
 
64
56
  def json_headers
@@ -68,19 +60,20 @@ module KnapsackPro
68
60
  'KNAPSACK-PRO-CLIENT-NAME' => client_name,
69
61
  'KNAPSACK-PRO-CLIENT-VERSION' => KnapsackPro::VERSION,
70
62
  'KNAPSACK-PRO-TEST-SUITE-TOKEN' => KnapsackPro::Config::Env.test_suite_token,
71
- 'KNAPSACK-PRO-CI-PROVIDER' => KnapsackPro::Config::Env.ci_provider,
63
+ 'KNAPSACK-PRO-CI-PROVIDER' => KnapsackPro::Config::Env.ci_provider
72
64
  }.compact
73
65
  end
74
66
 
75
67
  def client_name
76
68
  [
77
69
  'knapsack_pro-ruby',
78
- ENV['KNAPSACK_PRO_TEST_RUNNER'],
70
+ ENV['KNAPSACK_PRO_TEST_RUNNER']
79
71
  ].compact.join('/')
80
72
  end
81
73
 
82
74
  def parse_response_body(body)
83
75
  return '' if body == '' || body.nil?
76
+
84
77
  JSON.parse(body)
85
78
  rescue JSON::ParserError
86
79
  nil
@@ -88,11 +81,8 @@ module KnapsackPro
88
81
 
89
82
  def seed
90
83
  return if @response_body.nil? || @response_body == ''
91
- response_body['build_distribution_id']
92
- end
93
84
 
94
- def has_seed?
95
- !seed.nil?
85
+ response_body['build_distribution_id']
96
86
  end
97
87
 
98
88
  def make_request(&block)
@@ -103,9 +93,9 @@ module KnapsackPro
103
93
 
104
94
  request_uuid = http_response.header['X-Request-Id'] || 'N/A'
105
95
 
106
- logger.debug("#{action.http_method.to_s.upcase} #{endpoint_url}")
96
+ logger.debug("#{action.http_method.to_s.upcase} #{endpoint_uri}")
107
97
  logger.debug("API request UUID: #{request_uuid}")
108
- logger.debug("Test suite split seed: #{seed}") if has_seed?
98
+ logger.debug("Test suite split seed: #{seed}") unless seed.nil?
109
99
  logger.debug('API response:')
110
100
  if errors?
111
101
  logger.error(response_body)
@@ -113,39 +103,95 @@ module KnapsackPro
113
103
  logger.debug(response_body)
114
104
  end
115
105
 
116
- if server_error?
117
- raise ServerError.new(response_body)
118
- end
106
+ raise ServerError.new(response_body) if server_error?
119
107
 
120
108
  response_body
121
- rescue ServerError, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EPIPE, EOFError, SocketError, Net::OpenTimeout, Net::ReadTimeout, OpenSSL::SSL::SSLError => e
122
- logger.warn("#{action.http_method.to_s.upcase} #{endpoint_url}")
123
- logger.warn('Request failed due to:')
124
- logger.warn(e.inspect)
109
+ rescue ServerError, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EPIPE, EOFError,
110
+ SocketError, Net::OpenTimeout, Net::ReadTimeout, OpenSSL::SSL::SSLError => e
125
111
  retries += 1
112
+ log_diagnostics(e, retries)
113
+ @http.set_debug_output(@http_debug_output) if retries == max_request_retries - 1
126
114
  if retries < max_request_retries
127
- wait = retries * REQUEST_RETRY_TIMEBOX
128
- print_every = 2 # seconds
129
- (wait / print_every).ceil.times do |i|
130
- if i == 0
131
- logger.warn("Wait for #{wait}s before retrying the request to Knapsack Pro API.")
132
- else
133
- logger.warn("#{wait - i * print_every}s left before retry...")
134
- end
135
- Kernel.sleep(print_every)
136
- end
115
+ backoff(retries)
116
+ rotate_ip
137
117
  retry
138
118
  else
139
119
  response_body
140
120
  end
141
121
  end
142
122
 
123
+ def log_diagnostics(error, retries)
124
+ message = [
125
+ action.http_method.to_s.upcase,
126
+ endpoint_uri,
127
+ @http.ipaddr # value from @http.ipaddr= or nil
128
+ ].compact.join(' ')
129
+ logger.warn(message)
130
+ logger.warn('Request failed due to:')
131
+ logger.warn(error.inspect)
132
+ return if retries < max_request_retries
133
+
134
+ error.backtrace.each { |line| logger.warn(line) }
135
+ logger.warn('Net::HTTP debug output:')
136
+ @http_debug_output.string.each_line { |line| logger.warn(line.chomp) }
137
+
138
+ require 'open3'
139
+ [
140
+ "dig #{endpoint_uri.host}",
141
+ "nslookup #{endpoint_uri.host}",
142
+ "curl -v #{endpoint_uri.host}:#{endpoint_uri.port}",
143
+ "nc -vz #{endpoint_uri.host} #{endpoint_uri.port}",
144
+ "openssl s_client -connect #{endpoint_uri.host}:#{endpoint_uri.port} < /dev/null",
145
+ 'env'
146
+ ].each do |cmd|
147
+ logger.warn(cmd)
148
+ logger.warn('=' * cmd.size)
149
+ begin
150
+ outerr, status = Open3.capture2e(cmd)
151
+ logger.warn("Exit status: #{status.exitstatus}")
152
+ outerr.each_line { |line| logger.warn(line.chomp) }
153
+ rescue Errno::ENOENT => e
154
+ logger.warn("Error: #{e}")
155
+ end
156
+ end
157
+ end
158
+
159
+ def backoff(retries)
160
+ wait = retries * REQUEST_RETRY_TIMEBOX
161
+ print_every = 2 # seconds
162
+ (wait / print_every).ceil.times do |i|
163
+ if i.zero?
164
+ logger.warn("Wait for #{wait}s before retrying the request to the Knapsack Pro API.")
165
+ else
166
+ logger.warn("#{wait - i * print_every}s left before retry...")
167
+ end
168
+ Kernel.sleep(print_every)
169
+ end
170
+ end
171
+
143
172
  def build_http(uri)
144
- http = net_http.new(uri.host, uri.port)
145
- http.use_ssl = (uri.scheme == 'https')
146
- http.open_timeout = TIMEOUT
147
- http.read_timeout = TIMEOUT
148
- http
173
+ @http = net_http.new(uri.host, uri.port)
174
+ @http.use_ssl = (uri.scheme == 'https')
175
+ @http.open_timeout = TIMEOUT
176
+ @http.read_timeout = TIMEOUT
177
+ rotate_ip
178
+ end
179
+
180
+ def rotate_ip
181
+ # Ruby v3.4 implements Happy Eyeballs Version 2 (RFC 8305)
182
+ return if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.4')
183
+
184
+ @ipaddrs ||=
185
+ begin
186
+ require 'resolv'
187
+ resolvers = [
188
+ Resolv::Hosts.new,
189
+ Resolv::DNS.new(Resolv::DNS::Config.default_config_hash.merge(use_ipv6: false))
190
+ ]
191
+ Resolv.new(resolvers).getaddresses(endpoint_uri.host).shuffle
192
+ end
193
+
194
+ @http.ipaddr = @ipaddrs.rotate!.first
149
195
  end
150
196
 
151
197
  def net_http
@@ -157,19 +203,18 @@ module KnapsackPro
157
203
  end
158
204
 
159
205
  def post
160
- uri = URI.parse(endpoint_url)
161
- http = build_http(uri)
206
+ build_http(endpoint_uri)
162
207
  make_request do
163
- http.post(uri.path, request_body, json_headers)
208
+ @http.post(endpoint_uri.path, action.request_hash.to_json, json_headers)
164
209
  end
165
210
  end
166
211
 
167
212
  def get
168
- uri = URI.parse(endpoint_url)
169
- uri.query = URI.encode_www_form(request_hash)
170
- http = build_http(uri)
213
+ uri = endpoint_uri
214
+ uri.query = URI.encode_www_form(action.request_hash)
215
+ build_http(uri)
171
216
  make_request do
172
- http.get(uri, json_headers)
217
+ @http.get(uri, json_headers)
173
218
  end
174
219
  end
175
220
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables
3
+ # https://docs.github.com/en/actions/reference/workflows-and-actions/variables
4
4
  module KnapsackPro
5
5
  module Config
6
6
  module CI
@@ -31,9 +31,11 @@ module KnapsackPro
31
31
  end
32
32
 
33
33
  def branch
34
- # GITHUB_REF - The branch or tag ref that triggered the workflow. For example, refs/heads/feature-branch-1.
35
- # If neither a branch or tag is available for the event type, the variable will not exist.
36
- ENV['GITHUB_REF'] || ENV['GITHUB_SHA']
34
+ # `on: push` has `GITHUB_HEAD_REF=`
35
+ head_ref = ENV.fetch('GITHUB_HEAD_REF', '')
36
+ return head_ref unless head_ref == ''
37
+
38
+ ENV['GITHUB_REF_NAME'] || ENV['GITHUB_SHA']
37
39
  end
38
40
 
39
41
  def project_dir
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KnapsackPro
4
- VERSION = '8.4.0'
4
+ VERSION = '9.0.0'
5
5
  end
data/lib/knapsack_pro.rb CHANGED
@@ -29,7 +29,6 @@ require_relative 'knapsack_pro/config/ci/heroku'
29
29
  require_relative 'knapsack_pro/config/env'
30
30
  require_relative 'knapsack_pro/config/env_generator'
31
31
  require_relative 'knapsack_pro/config/temp_files'
32
- require_relative 'knapsack_pro/logger_wrapper'
33
32
  require_relative 'knapsack_pro/client/api/action'
34
33
  require_relative 'knapsack_pro/client/api/v1/base'
35
34
  require_relative 'knapsack_pro/client/api/v1/build_distributions'
@@ -91,6 +90,11 @@ require 'knapsack_pro/railtie' if defined?(Rails::Railtie)
91
90
 
92
91
  module KnapsackPro
93
92
  class << self
93
+ attr_writer :stdout
94
+ def stdout
95
+ @stdout ||= STDOUT
96
+ end
97
+
94
98
  def root
95
99
  File.expand_path('../..', __FILE__)
96
100
  end
@@ -103,15 +107,17 @@ module KnapsackPro
103
107
  end
104
108
 
105
109
  unless @logger
106
- default_logger = ::Logger.new(STDOUT)
110
+ default_logger = ::Logger.new(stdout)
107
111
  default_logger.level = KnapsackPro::Config::Env.log_level
108
112
  self.logger = default_logger
109
113
  end
114
+
110
115
  @logger
111
116
  end
112
117
 
113
118
  def logger=(logger)
114
- @logger = KnapsackPro::LoggerWrapper.new(logger)
119
+ @logger = logger
120
+ @logger.progname = 'knapsack_pro'
115
121
  end
116
122
 
117
123
  def reset_logger!
@@ -68,7 +68,7 @@ require 'tempfile'
68
68
 
69
69
  expect(actual.exit_code).to eq 1
70
70
 
71
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/regular-mode-connection-error-with-fallback-enabled-false')
71
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/regular-mode-connection-error-with-fallback-enabled-false')
72
72
  end
73
73
 
74
74
  context 'with a user defined exit code' do
@@ -85,7 +85,7 @@ require 'tempfile'
85
85
 
86
86
  expect(actual.exit_code).to eq 123
87
87
 
88
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/regular-mode-connection-error-with-fallback-enabled-false')
88
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/regular-mode-connection-error-with-fallback-enabled-false')
89
89
  end
90
90
  end
91
91
  end
@@ -106,7 +106,7 @@ require 'tempfile'
106
106
 
107
107
  expect(actual.exit_code).to eq 1
108
108
 
109
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/regular-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
109
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/regular-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
110
110
  end
111
111
 
112
112
  context 'with a user defined exit code' do
@@ -123,7 +123,7 @@ require 'tempfile'
123
123
 
124
124
  expect(actual.exit_code).to eq 123
125
125
 
126
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/regular-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
126
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/regular-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
127
127
  end
128
128
  end
129
129
  end
@@ -67,7 +67,7 @@ describe "#{KnapsackPro::Runners::Queue::CucumberRunner} Fallback - Integration
67
67
 
68
68
  expect(actual.exit_code).to eq 1
69
69
 
70
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-false')
70
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-false')
71
71
  end
72
72
 
73
73
  context 'with a user defined exit code' do
@@ -84,7 +84,7 @@ describe "#{KnapsackPro::Runners::Queue::CucumberRunner} Fallback - Integration
84
84
 
85
85
  expect(actual.exit_code).to eq 123
86
86
 
87
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-false')
87
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-false')
88
88
  end
89
89
  end
90
90
  end
@@ -105,7 +105,7 @@ describe "#{KnapsackPro::Runners::Queue::CucumberRunner} Fallback - Integration
105
105
 
106
106
  expect(actual.exit_code).to eq 1
107
107
 
108
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
108
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
109
109
  end
110
110
 
111
111
  context 'with a user defined exit code' do
@@ -122,7 +122,7 @@ describe "#{KnapsackPro::Runners::Queue::CucumberRunner} Fallback - Integration
122
122
 
123
123
  expect(actual.exit_code).to eq 123
124
124
 
125
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
125
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
126
126
  end
127
127
  end
128
128
  end
@@ -67,7 +67,7 @@ describe "#{KnapsackPro::Runners::Queue::MinitestRunner} Fallback - Integration
67
67
 
68
68
  expect(actual.exit_code).to eq 1
69
69
 
70
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-false')
70
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-false')
71
71
  end
72
72
 
73
73
  context 'with a user defined exit code' do
@@ -84,7 +84,7 @@ describe "#{KnapsackPro::Runners::Queue::MinitestRunner} Fallback - Integration
84
84
 
85
85
  expect(actual.exit_code).to eq 123
86
86
 
87
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-false')
87
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-false')
88
88
  end
89
89
  end
90
90
  end
@@ -105,7 +105,7 @@ describe "#{KnapsackPro::Runners::Queue::MinitestRunner} Fallback - Integration
105
105
 
106
106
  expect(actual.exit_code).to eq 1
107
107
 
108
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
108
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
109
109
  end
110
110
 
111
111
  context 'with a user defined exit code' do
@@ -122,7 +122,7 @@ describe "#{KnapsackPro::Runners::Queue::MinitestRunner} Fallback - Integration
122
122
 
123
123
  expect(actual.exit_code).to eq 123
124
124
 
125
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
125
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
126
126
  end
127
127
  end
128
128
  end
@@ -67,7 +67,7 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} Fallback - Integration tes
67
67
 
68
68
  expect(actual.exit_code).to eq 1
69
69
 
70
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-false')
70
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-false')
71
71
  expect(actual.stdout).to include(/Finished in .* seconds \(files took .* seconds to load\)/)
72
72
  expect(actual.stdout).to include('0 examples, 0 failures')
73
73
  end
@@ -86,7 +86,7 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} Fallback - Integration tes
86
86
 
87
87
  expect(actual.exit_code).to eq 123
88
88
 
89
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-false')
89
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: Fallback Mode was disabled with KNAPSACK_PRO_FALLBACK_MODE_ENABLED=false. Please restart this CI node to retry tests. Most likely Fallback Mode was disabled due to https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-false')
90
90
  expect(actual.stdout).to include(/Finished in .* seconds \(files took .* seconds to load\)/)
91
91
  expect(actual.stdout).to include('0 examples, 0 failures')
92
92
  end
@@ -109,7 +109,7 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} Fallback - Integration tes
109
109
 
110
110
  expect(actual.exit_code).to eq 1
111
111
 
112
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
112
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
113
113
  expect(actual.stdout).to include(/Finished in .* seconds \(files took .* seconds to load\)/)
114
114
  expect(actual.stdout).to include('0 examples, 0 failures')
115
115
  end
@@ -128,7 +128,7 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} Fallback - Integration tes
128
128
 
129
129
  expect(actual.exit_code).to eq 123
130
130
 
131
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
131
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: knapsack_pro gem could not connect to Knapsack Pro API and the Fallback Mode cannot be used this time. Running tests in Fallback Mode are not allowed for retried parallel CI node to avoid running the wrong set of tests. Please manually retry this parallel job on your CI server then knapsack_pro gem will try to connect to Knapsack Pro API again and will run a correct set of tests for this CI node. Learn more https://knapsackpro.com/perma/ruby/queue-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count')
132
132
  expect(actual.stdout).to include(/Finished in .* seconds \(files took .* seconds to load\)/)
133
133
  expect(actual.stdout).to include('0 examples, 0 failures')
134
134
  end
@@ -137,22 +137,22 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
137
137
 
138
138
  actual = subject
139
139
 
140
- expect(actual.stdout).to include('DEBUG -- : [knapsack_pro] Queue Mode enabled.')
140
+ expect(actual.stdout).to include('DEBUG -- knapsack_pro: Queue Mode enabled.')
141
141
 
142
142
  expect(actual.stdout).to include('A1 test example')
143
143
  expect(actual.stdout).to include('B1 test example')
144
144
  expect(actual.stdout).to include('C1 test example')
145
145
 
146
- expect(actual.stdout).to include('INFO -- : [knapsack_pro] To retry the last batch of tests fetched from the Queue API, please run the following command on your machine:')
147
- expect(actual.stdout).to include('INFO -- : [knapsack_pro] bundle exec rspec --format d --default-path spec_integration "spec_integration/a_spec.rb" "spec_integration/b_spec.rb"')
148
- expect(actual.stdout).to include('INFO -- : [knapsack_pro] bundle exec rspec --format d --default-path spec_integration "spec_integration/c_spec.rb"')
146
+ expect(actual.stdout).to include('INFO -- knapsack_pro: To retry the last batch of tests fetched from the Queue API, please run the following command on your machine:')
147
+ expect(actual.stdout).to include('INFO -- knapsack_pro: bundle exec rspec --format d --default-path spec_integration "spec_integration/a_spec.rb" "spec_integration/b_spec.rb"')
148
+ expect(actual.stdout).to include('INFO -- knapsack_pro: bundle exec rspec --format d --default-path spec_integration "spec_integration/c_spec.rb"')
149
149
 
150
- expect(actual.stdout).to include('INFO -- : [knapsack_pro] To retry all the tests assigned to this CI node, please run the following command on your machine:')
151
- expect(actual.stdout).to include('INFO -- : [knapsack_pro] bundle exec rspec --format d --default-path spec_integration "spec_integration/a_spec.rb" "spec_integration/b_spec.rb" "spec_integration/c_spec.rb"')
150
+ expect(actual.stdout).to include('INFO -- knapsack_pro: To retry all the tests assigned to this CI node, please run the following command on your machine:')
151
+ expect(actual.stdout).to include('INFO -- knapsack_pro: bundle exec rspec --format d --default-path spec_integration "spec_integration/a_spec.rb" "spec_integration/b_spec.rb" "spec_integration/c_spec.rb"')
152
152
 
153
153
  expect(actual.stdout).to include('3 examples, 0 failures')
154
154
 
155
- expect(actual.stdout).to include('DEBUG -- : [knapsack_pro] Global test execution duration:')
155
+ expect(actual.stdout).to include('DEBUG -- knapsack_pro: Global test execution duration:')
156
156
 
157
157
  expect(actual.exit_code).to eq 0
158
158
  end
@@ -230,7 +230,7 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
230
230
 
231
231
  actual = subject
232
232
 
233
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] You forgot to call KnapsackPro::Adapters::RSpecAdapter.bind method in your test runner configuration file. It is needed to record test files time execution. Please follow the installation guide to configure your project properly https://knapsackpro.com/perma/ruby/installation-guide')
233
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: You forgot to call KnapsackPro::Adapters::RSpecAdapter.bind method in your test runner configuration file. It is needed to record test files time execution. Please follow the installation guide to configure your project properly https://knapsackpro.com/perma/ruby/installation-guide')
234
234
 
235
235
  expect(actual.exit_code).to eq 1
236
236
  end
@@ -917,12 +917,12 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
917
917
  expect(actual.stdout).to include('Randomized with seed 123')
918
918
 
919
919
  # 1st batch
920
- expect(actual.stdout).to include('INFO -- : [knapsack_pro] bundle exec rspec --order rand:123 --format progress --default-path spec_integration "spec_integration/a_spec.rb" "spec_integration/b_spec.rb"')
920
+ expect(actual.stdout).to include('INFO -- knapsack_pro: bundle exec rspec --order rand:123 --format progress --default-path spec_integration "spec_integration/a_spec.rb" "spec_integration/b_spec.rb"')
921
921
  # 2nd batch
922
- expect(actual.stdout).to include('INFO -- : [knapsack_pro] bundle exec rspec --order rand:123 --format progress --default-path spec_integration "spec_integration/c_spec.rb"')
922
+ expect(actual.stdout).to include('INFO -- knapsack_pro: bundle exec rspec --order rand:123 --format progress --default-path spec_integration "spec_integration/c_spec.rb"')
923
923
 
924
924
  # the final RSpec command with seed
925
- expect(actual.stdout).to include('INFO -- : [knapsack_pro] bundle exec rspec --order rand:123 --format progress --default-path spec_integration "spec_integration/a_spec.rb" "spec_integration/b_spec.rb" "spec_integration/c_spec.rb"')
925
+ expect(actual.stdout).to include('INFO -- knapsack_pro: bundle exec rspec --order rand:123 --format progress --default-path spec_integration "spec_integration/a_spec.rb" "spec_integration/b_spec.rb" "spec_integration/c_spec.rb"')
926
926
 
927
927
  expect(actual.exit_code).to eq 0
928
928
  end
@@ -1061,7 +1061,7 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
1061
1061
 
1062
1062
  expect(actual.stdout).to include('An error occurred while loading ./spec_integration/failing_spec.rb')
1063
1063
  expect(actual.stdout).to match(/undefined local variable or method .a_fake_method. for.* RSpec::ExampleGroups::BDescribe/)
1064
- expect(actual.stdout).to include('WARN -- : [knapsack_pro] RSpec wants to quit')
1064
+ expect(actual.stdout).to include('WARN -- knapsack_pro: RSpec wants to quit')
1065
1065
  expect(actual.stdout).to include('1 example, 0 failures, 1 error occurred outside of examples')
1066
1066
 
1067
1067
  expect(actual.exit_code).to eq 1
@@ -1263,7 +1263,7 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
1263
1263
  # It breaks RSpec so it was not marked as failed.
1264
1264
  expect(actual.stdout).to include('2 examples, 0 failures')
1265
1265
 
1266
- expect(actual.stdout).to include('WARN -- : [knapsack_pro] Unexecuted tests on this CI node (including pending tests): spec_integration/b_spec.rb')
1266
+ expect(actual.stdout).to include('WARN -- knapsack_pro: Unexecuted tests on this CI node (including pending tests): spec_integration/b_spec.rb')
1267
1267
 
1268
1268
  expect(actual.exit_code).to eq 1
1269
1269
  end
@@ -1497,7 +1497,7 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
1497
1497
 
1498
1498
  actual = subject
1499
1499
 
1500
- expect(actual.stdout).to include('ERROR -- : [knapsack_pro] The run_all_when_everything_filtered option is deprecated. See: https://knapsackpro.com/perma/ruby/rspec-deprecated-run-all-when-everything-filtered')
1500
+ expect(actual.stdout).to include('ERROR -- knapsack_pro: The run_all_when_everything_filtered option is deprecated. See: https://knapsackpro.com/perma/ruby/rspec-deprecated-run-all-when-everything-filtered')
1501
1501
 
1502
1502
  expect(actual.stdout).to_not include('A1 test example')
1503
1503
  expect(actual.stdout).to_not include('B1 test example')
@@ -1576,8 +1576,8 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
1576
1576
  actual = subject
1577
1577
 
1578
1578
  expect(actual.stdout).to include('0 examples, 0 failures')
1579
- expect(actual.stdout).to include('WARN -- : [knapsack_pro] No test files were executed on this CI node.')
1580
- expect(actual.stdout).to include('DEBUG -- : [knapsack_pro] This CI node likely started work late after the test files were already executed by other CI nodes consuming the queue.')
1579
+ expect(actual.stdout).to include('WARN -- knapsack_pro: No test files were executed on this CI node.')
1580
+ expect(actual.stdout).to include('DEBUG -- knapsack_pro: This CI node likely started work late after the test files were already executed by other CI nodes consuming the queue.')
1581
1581
 
1582
1582
  expect(actual.exit_code).to eq 0
1583
1583
  end
@@ -1601,8 +1601,8 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
1601
1601
  actual = subject
1602
1602
 
1603
1603
  expect(actual.stdout).to include('0 examples, 0 failures')
1604
- expect(actual.stdout).to include('WARN -- : [knapsack_pro] No test files were executed on this CI node.')
1605
- expect(actual.stdout).to include('DEBUG -- : [knapsack_pro] This CI node likely started work late after the test files were already executed by other CI nodes consuming the queue.')
1604
+ expect(actual.stdout).to include('WARN -- knapsack_pro: No test files were executed on this CI node.')
1605
+ expect(actual.stdout).to include('DEBUG -- knapsack_pro: This CI node likely started work late after the test files were already executed by other CI nodes consuming the queue.')
1606
1606
 
1607
1607
  expect(actual.exit_code).to eq 0
1608
1608
  end
@@ -1821,7 +1821,7 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
1821
1821
  expect(actual.stdout).to_not include('C1 test example')
1822
1822
  expect(actual.stdout).to_not include('C2 test example')
1823
1823
 
1824
- expect(actual.stdout).to include('WARN -- : [knapsack_pro] Test execution has been canceled because the RSpec --fail-fast option is enabled. It will cause other CI nodes to run tests longer because they need to consume more tests from the Knapsack Pro Queue API.')
1824
+ expect(actual.stdout).to include('WARN -- knapsack_pro: Test execution has been canceled because the RSpec --fail-fast option is enabled. It will cause other CI nodes to run tests longer because they need to consume more tests from the Knapsack Pro Queue API.')
1825
1825
 
1826
1826
  expect(actual.stdout).to include('2 examples, 1 failure')
1827
1827
 
@@ -1885,7 +1885,7 @@ describe "#{KnapsackPro::Runners::Queue::RSpecRunner} - Integration tests", :cle
1885
1885
  expect(actual.stdout).to_not include('C1 test example')
1886
1886
  expect(actual.stdout).to_not include('C2 test example')
1887
1887
 
1888
- expect(actual.stdout).to include('WARN -- : [knapsack_pro] Test execution has been canceled because the RSpec --fail-fast option is enabled. It will cause other CI nodes to run tests longer because they need to consume more tests from the Knapsack Pro Queue API.')
1888
+ expect(actual.stdout).to include('WARN -- knapsack_pro: Test execution has been canceled because the RSpec --fail-fast option is enabled. It will cause other CI nodes to run tests longer because they need to consume more tests from the Knapsack Pro Queue API.')
1889
1889
 
1890
1890
  expect(actual.stdout).to include('3 examples, 2 failures')
1891
1891
 
@@ -72,6 +72,9 @@ shared_examples 'when retry request' do
72
72
 
73
73
  before do
74
74
  expect(KnapsackPro).to receive(:logger).at_least(1).and_return(logger)
75
+ allow(http).to receive(:set_debug_output)
76
+ allow(http).to receive(:ipaddr).and_return(nil)
77
+ allow(logger).to receive(:warn).at_least(:once)
75
78
  end
76
79
 
77
80
  it do
@@ -88,11 +91,11 @@ shared_examples 'when retry request' do
88
91
  expect(logger).to receive(:warn).exactly(3).with('Request failed due to:')
89
92
  expect(logger).to receive(:warn).exactly(3).with(server_error.inspect)
90
93
 
91
- expect(logger).to receive(:warn).with("Wait for 8s before retrying the request to Knapsack Pro API.")
94
+ expect(logger).to receive(:warn).with("Wait for 8s before retrying the request to the Knapsack Pro API.")
92
95
  expect(logger).to receive(:warn).with("6s left before retry...")
93
96
  expect(logger).to receive(:warn).with("4s left before retry...")
94
97
  expect(logger).to receive(:warn).with("2s left before retry...")
95
- expect(logger).to receive(:warn).with("Wait for 16s before retrying the request to Knapsack Pro API.")
98
+ expect(logger).to receive(:warn).with("Wait for 16s before retrying the request to the Knapsack Pro API.")
96
99
  expect(logger).to receive(:warn).with("14s left before retry...")
97
100
  expect(logger).to receive(:warn).with("12s left before retry...")
98
101
  expect(logger).to receive(:warn).with("10s left before retry...")
@@ -127,12 +130,12 @@ shared_examples 'when retry request' do
127
130
  expect(logger).to receive(:warn).exactly(4).with('Request failed due to:')
128
131
  expect(logger).to receive(:warn).exactly(4).with(server_error.inspect)
129
132
 
130
- expect(logger).to receive(:warn).with("Wait for 8s before retrying the request to Knapsack Pro API.")
133
+ expect(logger).to receive(:warn).with("Wait for 8s before retrying the request to the Knapsack Pro API.")
131
134
  expect(logger).to receive(:warn).with("6s left before retry...")
132
135
  expect(logger).to receive(:warn).with("4s left before retry...")
133
136
  expect(logger).to receive(:warn).with("2s left before retry...")
134
137
 
135
- expect(logger).to receive(:warn).with("Wait for 16s before retrying the request to Knapsack Pro API.")
138
+ expect(logger).to receive(:warn).with("Wait for 16s before retrying the request to the Knapsack Pro API.")
136
139
  expect(logger).to receive(:warn).with("14s left before retry...")
137
140
  expect(logger).to receive(:warn).with("12s left before retry...")
138
141
  expect(logger).to receive(:warn).with("10s left before retry...")
@@ -141,7 +144,7 @@ shared_examples 'when retry request' do
141
144
  expect(logger).to receive(:warn).with("4s left before retry...")
142
145
  expect(logger).to receive(:warn).with("2s left before retry...")
143
146
 
144
- expect(logger).to receive(:warn).with("Wait for 24s before retrying the request to Knapsack Pro API.")
147
+ expect(logger).to receive(:warn).with("Wait for 24s before retrying the request to the Knapsack Pro API.")
145
148
  11.times do |i|
146
149
  expect(logger).to receive(:warn).with("#{(i+1)*2}s left before retry...")
147
150
  end
@@ -174,12 +177,12 @@ shared_examples 'when retry request' do
174
177
  expect(logger).to receive(:warn).exactly(6).with('Request failed due to:')
175
178
  expect(logger).to receive(:warn).exactly(6).with(server_error.inspect)
176
179
 
177
- expect(logger).to receive(:warn).with("Wait for 8s before retrying the request to Knapsack Pro API.")
180
+ expect(logger).to receive(:warn).with("Wait for 8s before retrying the request to the Knapsack Pro API.")
178
181
  expect(logger).to receive(:warn).with("6s left before retry...")
179
182
  expect(logger).to receive(:warn).with("4s left before retry...")
180
183
  expect(logger).to receive(:warn).with("2s left before retry...")
181
184
 
182
- expect(logger).to receive(:warn).with("Wait for 16s before retrying the request to Knapsack Pro API.")
185
+ expect(logger).to receive(:warn).with("Wait for 16s before retrying the request to the Knapsack Pro API.")
183
186
  expect(logger).to receive(:warn).with("14s left before retry...")
184
187
  expect(logger).to receive(:warn).with("12s left before retry...")
185
188
  expect(logger).to receive(:warn).with("10s left before retry...")
@@ -188,17 +191,17 @@ shared_examples 'when retry request' do
188
191
  expect(logger).to receive(:warn).with("4s left before retry...")
189
192
  expect(logger).to receive(:warn).with("2s left before retry...")
190
193
 
191
- expect(logger).to receive(:warn).with("Wait for 24s before retrying the request to Knapsack Pro API.")
194
+ expect(logger).to receive(:warn).with("Wait for 24s before retrying the request to the Knapsack Pro API.")
192
195
  11.times do |i|
193
196
  expect(logger).to receive(:warn).with("#{(i+1)*2}s left before retry...")
194
197
  end
195
198
 
196
- expect(logger).to receive(:warn).with("Wait for 32s before retrying the request to Knapsack Pro API.")
199
+ expect(logger).to receive(:warn).with("Wait for 32s before retrying the request to the Knapsack Pro API.")
197
200
  15.times do |i|
198
201
  expect(logger).to receive(:warn).with("#{(i+1)*2}s left before retry...")
199
202
  end
200
203
 
201
- expect(logger).to receive(:warn).with("Wait for 40s before retrying the request to Knapsack Pro API.")
204
+ expect(logger).to receive(:warn).with("Wait for 40s before retrying the request to the Knapsack Pro API.")
202
205
  19.times do |i|
203
206
  expect(logger).to receive(:warn).with("#{(i+1)*2}s left before retry...")
204
207
  end
@@ -231,12 +234,12 @@ shared_examples 'when retry request' do
231
234
  expect(logger).to receive(:warn).exactly(6).with('Request failed due to:')
232
235
  expect(logger).to receive(:warn).exactly(6).with(server_error.inspect)
233
236
 
234
- expect(logger).to receive(:warn).with("Wait for 8s before retrying the request to Knapsack Pro API.")
237
+ expect(logger).to receive(:warn).with("Wait for 8s before retrying the request to the Knapsack Pro API.")
235
238
  expect(logger).to receive(:warn).with("6s left before retry...")
236
239
  expect(logger).to receive(:warn).with("4s left before retry...")
237
240
  expect(logger).to receive(:warn).with("2s left before retry...")
238
241
 
239
- expect(logger).to receive(:warn).with("Wait for 16s before retrying the request to Knapsack Pro API.")
242
+ expect(logger).to receive(:warn).with("Wait for 16s before retrying the request to the Knapsack Pro API.")
240
243
  expect(logger).to receive(:warn).with("14s left before retry...")
241
244
  expect(logger).to receive(:warn).with("12s left before retry...")
242
245
  expect(logger).to receive(:warn).with("10s left before retry...")
@@ -245,17 +248,17 @@ shared_examples 'when retry request' do
245
248
  expect(logger).to receive(:warn).with("4s left before retry...")
246
249
  expect(logger).to receive(:warn).with("2s left before retry...")
247
250
 
248
- expect(logger).to receive(:warn).with("Wait for 24s before retrying the request to Knapsack Pro API.")
251
+ expect(logger).to receive(:warn).with("Wait for 24s before retrying the request to the Knapsack Pro API.")
249
252
  11.times do |i|
250
253
  expect(logger).to receive(:warn).with("#{(i+1)*2}s left before retry...")
251
254
  end
252
255
 
253
- expect(logger).to receive(:warn).with("Wait for 32s before retrying the request to Knapsack Pro API.")
256
+ expect(logger).to receive(:warn).with("Wait for 32s before retrying the request to the Knapsack Pro API.")
254
257
  15.times do |i|
255
258
  expect(logger).to receive(:warn).with("#{(i+1)*2}s left before retry...")
256
259
  end
257
260
 
258
- expect(logger).to receive(:warn).with("Wait for 40s before retrying the request to Knapsack Pro API.")
261
+ expect(logger).to receive(:warn).with("Wait for 40s before retrying the request to the Knapsack Pro API.")
259
262
  19.times do |i|
260
263
  expect(logger).to receive(:warn).with("#{(i+1)*2}s left before retry...")
261
264
  end
@@ -311,6 +314,7 @@ describe KnapsackPro::Client::Connection do
311
314
  expect(http).to receive(:use_ssl=).with(false)
312
315
  expect(http).to receive(:open_timeout=).with(15)
313
316
  expect(http).to receive(:read_timeout=).with(15)
317
+ allow(http).to receive(:ipaddr=).at_least(:once)
314
318
  end
315
319
 
316
320
  context 'when http method is POST on GitHub Actions' do
@@ -61,30 +61,52 @@ describe KnapsackPro::Config::CI::GithubActions do
61
61
  describe '#branch' do
62
62
  subject { described_class.new.branch }
63
63
 
64
- context 'when the environment exists' do
65
- context 'when GITHUB_REF has value' do
66
- let(:env) do
67
- {
68
- 'GITHUB_REF' => 'main',
69
- 'GITHUB_SHA' => '2e13512fc230d6f9ebf4923352718e4d',
70
- }
71
- end
72
-
73
- it { should eql 'main' }
64
+ context 'when GITHUB_HEAD_REF is set' do
65
+ let(:env) do
66
+ {
67
+ 'GITHUB_HEAD_REF' => 'feature',
68
+ 'GITHUB_REF_NAME' => 'main',
69
+ 'GITHUB_SHA' => '2e13512fc230d6f9ebf4923352718e4d'
70
+ }
74
71
  end
75
72
 
76
- context 'when GITHUB_REF is not set' do
77
- let(:env) do
78
- {
79
- 'GITHUB_SHA' => '2e13512fc230d6f9ebf4923352718e4d',
80
- }
81
- end
73
+ it { should eql 'feature' }
74
+ end
82
75
 
83
- it { should eql '2e13512fc230d6f9ebf4923352718e4d' }
76
+ context 'when GITHUB_REF_NAME is set' do
77
+ let(:env) do
78
+ {
79
+ 'GITHUB_REF_NAME' => 'main',
80
+ 'GITHUB_SHA' => '2e13512fc230d6f9ebf4923352718e4d'
81
+ }
84
82
  end
83
+
84
+ it { should eql 'main' }
85
85
  end
86
86
 
87
- context "when the environment doesn't exist" do
87
+ context 'when GITHUB_HEAD_REF is set to empty string' do
88
+ let(:env) do
89
+ {
90
+ 'GITHUB_HEAD_REF' => '',
91
+ 'GITHUB_REF_NAME' => 'main',
92
+ 'GITHUB_SHA' => '2e13512fc230d6f9ebf4923352718e4d'
93
+ }
94
+ end
95
+
96
+ it { should eql 'main' }
97
+ end
98
+
99
+ context 'when GITHUB_SHA is set' do
100
+ let(:env) do
101
+ {
102
+ 'GITHUB_SHA' => '2e13512fc230d6f9ebf4923352718e4d'
103
+ }
104
+ end
105
+
106
+ it { should eql '2e13512fc230d6f9ebf4923352718e4d' }
107
+ end
108
+
109
+ context 'with no ENVs' do
88
110
  it { should be nil }
89
111
  end
90
112
  end
@@ -59,7 +59,7 @@ describe KnapsackPro::Pure::Queue::RSpecPure do
59
59
 
60
60
  context 'when the order option is not random' do
61
61
  let(:args) { ['--order', 'defined'] }
62
- let(:seed) { KnapsackPro::Extensions::RSpecExtension::Seed.new(value: nil, used?: false) }
62
+ let(:seed) { KnapsackPro::Extensions::RSpecExtension::Seed.new(nil, false) }
63
63
 
64
64
  it 'does not add the seed option to args' do
65
65
  expect(subject).to eq ['--order', 'defined']
@@ -71,7 +71,7 @@ describe KnapsackPro::Pure::Queue::RSpecPure do
71
71
  let(:args) { ['--order', random_option_value] }
72
72
 
73
73
  context 'when the seed is not used' do
74
- let(:seed) { KnapsackPro::Extensions::RSpecExtension::Seed.new(value: '123', used?: false) }
74
+ let(:seed) { KnapsackPro::Extensions::RSpecExtension::Seed.new('123', false) }
75
75
 
76
76
  it 'does not add the seed option to args' do
77
77
  expect(subject).to eq ['--order', random_option_value]
@@ -79,7 +79,7 @@ describe KnapsackPro::Pure::Queue::RSpecPure do
79
79
  end
80
80
 
81
81
  context 'when the seed is used' do
82
- let(:seed) { KnapsackPro::Extensions::RSpecExtension::Seed.new(value: '123', used?: true) }
82
+ let(:seed) { KnapsackPro::Extensions::RSpecExtension::Seed.new('123', true) }
83
83
 
84
84
  it 'adds the seed option to args' do
85
85
  expect(subject).to eq ['--order', random_option_value, '--seed', '123']
@@ -90,7 +90,7 @@ describe KnapsackPro::Pure::Queue::RSpecPure do
90
90
 
91
91
  context 'when the order option is `rand:123`' do
92
92
  let(:args) { ['--order', 'rand:123'] }
93
- let(:seed) { KnapsackPro::Extensions::RSpecExtension::Seed.new(value: '123', used?: true) }
93
+ let(:seed) { KnapsackPro::Extensions::RSpecExtension::Seed.new('123', true) }
94
94
 
95
95
  it 'does not add the seed option to args' do
96
96
  expect(subject).to eq ['--order', 'rand:123']
@@ -99,7 +99,7 @@ describe KnapsackPro::Pure::Queue::RSpecPure do
99
99
 
100
100
  context 'when the order option is not set in args AND seed is used' do
101
101
  let(:args) { ['--format', 'documentation'] }
102
- let(:seed) { KnapsackPro::Extensions::RSpecExtension::Seed.new(value: '123', used?: true) }
102
+ let(:seed) { KnapsackPro::Extensions::RSpecExtension::Seed.new('123', true) }
103
103
 
104
104
  it 'adds the seed option to args' do
105
105
  expect(subject).to eq ['--format', 'documentation', '--seed', '123']
@@ -148,7 +148,7 @@ describe KnapsackPro::TestCaseDetectors::RSpecTestExampleDetector do
148
148
  subject_class.new.generate_json_report(rspec_args)
149
149
  end
150
150
  .to output(/Please only use one of `--force-color` and `--no-color`/).to_stderr
151
- .and output(%r{ERROR -- : \[knapsack_pro\] Failed to generate the slow test files report: bundle exec rspec --no-color --force-color --format json --dry-run --out .knapsack_pro/test_case_detectors/rspec/rspec_dry_run_json_report_node_0.json --default-path spec spec/a_spec.rb}).to_stdout
151
+ .and output(%r{ERROR -- knapsack_pro: Failed to generate the slow test files report: bundle exec rspec --no-color --force-color --format json --dry-run --out .knapsack_pro/test_case_detectors/rspec/rspec_dry_run_json_report_node_0.json --default-path spec spec/a_spec.rb}).to_stdout
152
152
  .and raise_error(SystemExit) { |error| expect(error.status).to eq 1 }
153
153
  end
154
154
  end
@@ -1,3 +1,5 @@
1
+ require 'tmpdir'
2
+
1
3
  describe KnapsackPro do
2
4
  describe '.root' do
3
5
  subject { described_class.root }
@@ -6,70 +8,92 @@ describe KnapsackPro do
6
8
  end
7
9
 
8
10
  describe '.logger' do
9
- let(:logger_wrapper) { double }
10
-
11
11
  subject { described_class.logger }
12
12
 
13
13
  before(:each) do
14
14
  described_class.reset_logger!
15
15
  KnapsackPro::Config::Env.remove_instance_variable(:@ci_node_index) if KnapsackPro::Config::Env.instance_variable_defined?(:@ci_node_index)
16
16
  end
17
+
17
18
  after { described_class.reset_logger! }
18
19
 
19
20
  context 'when KNAPSACK_PRO_LOG_DIR is set' do
20
- let(:logger) { instance_double(Logger) }
21
-
22
21
  context 'when KNAPSACK_PRO_CI_NODE_INDEX is set' do
23
- before do
24
- stub_const('ENV', {
25
- 'KNAPSACK_PRO_LOG_DIR' => 'log',
26
- 'KNAPSACK_PRO_CI_NODE_INDEX' => 1,
27
- })
28
-
29
- expect(Logger).to receive(:new).with('log/knapsack_pro_node_1.log').and_return(logger)
30
- expect(logger).to receive(:level=).with(Logger::INFO)
31
- expect(KnapsackPro::LoggerWrapper).to receive(:new).with(logger).and_return(logger_wrapper)
22
+ it 'logs to a file in that dir named after the node index' do
23
+ Dir.mktmpdir do |dir|
24
+ stub_const('ENV', 'KNAPSACK_PRO_LOG_DIR' => dir, 'KNAPSACK_PRO_CI_NODE_INDEX' => 1)
25
+
26
+ KnapsackPro.logger.debug 'debug'
27
+ KnapsackPro.logger.info 'info'
28
+ KnapsackPro.logger.warn 'warn'
29
+
30
+ log = File.read "#{dir}/knapsack_pro_node_1.log"
31
+ expect(log).not_to include('DEBUG -- knapsack_pro: debug')
32
+ expect(log).to include('INFO -- knapsack_pro: info')
33
+ expect(log).to include('WARN -- knapsack_pro: warn')
34
+ end
32
35
  end
33
-
34
- it { should eql logger_wrapper }
35
36
  end
36
37
 
37
38
  context 'when KNAPSACK_PRO_CI_NODE_INDEX is not set' do
38
- before do
39
- stub_const('ENV', {
40
- 'KNAPSACK_PRO_LOG_DIR' => 'log',
41
- })
42
-
43
- expect(Logger).to receive(:new).with('log/knapsack_pro_node_0.log').and_return(logger)
44
- expect(logger).to receive(:level=).with(Logger::INFO)
45
- expect(KnapsackPro::LoggerWrapper).to receive(:new).with(logger).and_return(logger_wrapper)
39
+ it 'logs to a file in that dir named after node index 0' do
40
+ Dir.mktmpdir do |dir|
41
+ stub_const('ENV', 'KNAPSACK_PRO_LOG_DIR' => dir)
42
+
43
+ KnapsackPro.logger.debug 'debug'
44
+ KnapsackPro.logger.info 'info'
45
+ KnapsackPro.logger.warn 'warn'
46
+
47
+ log = File.read "#{dir}/knapsack_pro_node_0.log"
48
+ expect(log).not_to include('DEBUG -- knapsack_pro: debug')
49
+ expect(log).to include('INFO -- knapsack_pro: info')
50
+ expect(log).to include('WARN -- knapsack_pro: warn')
51
+ end
46
52
  end
47
-
48
- it { should eql logger_wrapper }
49
53
  end
50
54
  end
51
55
 
52
- context 'when default logger' do
53
- let(:logger) { instance_double(Logger) }
56
+ context 'with the default logger' do
57
+ it 'ignores debug to stdout' do
58
+ expect do
59
+ KnapsackPro.stdout = $stdout
60
+ KnapsackPro.logger.debug 'debug'
61
+ end
62
+ .not_to output.to_stdout
63
+ end
54
64
 
55
- before do
56
- expect(Logger).to receive(:new).with(STDOUT).and_return(logger)
57
- expect(logger).to receive(:level=).with(Logger::INFO)
58
- expect(KnapsackPro::LoggerWrapper).to receive(:new).with(logger).and_return(logger_wrapper)
65
+ it 'logs info to stdout' do
66
+ expect do
67
+ KnapsackPro.stdout = $stdout
68
+ KnapsackPro.logger.info 'info'
69
+ end
70
+ .to output(/INFO -- knapsack_pro: info/)
71
+ .to_stdout
59
72
  end
60
73
 
61
- it { should eql logger_wrapper }
74
+ it 'logs warn to stdout' do
75
+ expect do
76
+ KnapsackPro.stdout = $stdout
77
+ KnapsackPro.logger.warn 'warn'
78
+ end
79
+ .to output(/WARN -- knapsack_pro: warn/)
80
+ .to_stdout
81
+ end
62
82
  end
63
83
 
64
- context 'when custom logger' do
65
- let(:logger) { double('custom logger') }
84
+ context 'with a custom logger' do
85
+ it 'logs using it' do
86
+ stream = StringIO.new
87
+ KnapsackPro.logger = ::Logger.new(stream)
66
88
 
67
- before do
68
- expect(KnapsackPro::LoggerWrapper).to receive(:new).with(logger).and_return(logger_wrapper)
69
- described_class.logger = logger
70
- end
89
+ KnapsackPro.logger.debug 'debug'
90
+ KnapsackPro.logger.info 'info'
91
+ KnapsackPro.logger.warn 'warn'
71
92
 
72
- it { should eql logger_wrapper }
93
+ expect(stream.string).to include('DEBUG -- knapsack_pro: debug')
94
+ expect(stream.string).to include('INFO -- knapsack_pro: info')
95
+ expect(stream.string).to include('WARN -- knapsack_pro: warn')
96
+ end
73
97
  end
74
98
  end
75
99
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knapsack_pro
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.4.0
4
+ version: 9.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ArturT
@@ -257,7 +257,6 @@ files:
257
257
  - lib/knapsack_pro/formatters/time_tracker.rb
258
258
  - lib/knapsack_pro/formatters/time_tracker_fetcher.rb
259
259
  - lib/knapsack_pro/hooks/queue.rb
260
- - lib/knapsack_pro/logger_wrapper.rb
261
260
  - lib/knapsack_pro/mask_string.rb
262
261
  - lib/knapsack_pro/presenter.rb
263
262
  - lib/knapsack_pro/pure/queue/rspec_pure.rb
@@ -360,7 +359,6 @@ files:
360
359
  - spec/knapsack_pro/formatters/time_tracker_fetcher_spec.rb
361
360
  - spec/knapsack_pro/formatters/time_tracker_spec.rb
362
361
  - spec/knapsack_pro/hooks/queue_spec.rb
363
- - spec/knapsack_pro/logger_wrapper_spec.rb
364
362
  - spec/knapsack_pro/presenter_spec.rb
365
363
  - spec/knapsack_pro/pure/queue/rspec_pure_spec.rb
366
364
  - spec/knapsack_pro/queue_spec.rb
@@ -421,14 +419,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
421
419
  requirements:
422
420
  - - ">="
423
421
  - !ruby/object:Gem::Version
424
- version: 2.7.0
422
+ version: 3.0.0
425
423
  required_rubygems_version: !ruby/object:Gem::Requirement
426
424
  requirements:
427
425
  - - ">="
428
426
  - !ruby/object:Gem::Version
429
427
  version: '0'
430
428
  requirements: []
431
- rubygems_version: 3.6.7
429
+ rubygems_version: 3.6.9
432
430
  specification_version: 4
433
431
  summary: Knapsack Pro splits tests across parallel CI nodes and ensures each parallel
434
432
  job finish work at a similar time.
@@ -483,7 +481,6 @@ test_files:
483
481
  - spec/knapsack_pro/formatters/time_tracker_fetcher_spec.rb
484
482
  - spec/knapsack_pro/formatters/time_tracker_spec.rb
485
483
  - spec/knapsack_pro/hooks/queue_spec.rb
486
- - spec/knapsack_pro/logger_wrapper_spec.rb
487
484
  - spec/knapsack_pro/presenter_spec.rb
488
485
  - spec/knapsack_pro/pure/queue/rspec_pure_spec.rb
489
486
  - spec/knapsack_pro/queue_spec.rb
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module KnapsackPro
4
- class LoggerWrapper
5
- def initialize(logger)
6
- @logger = logger
7
- end
8
-
9
- private
10
-
11
- attr_reader :logger
12
-
13
- LOG_LEVEL_METHODS = KnapsackPro::Config::Env::LOG_LEVELS.keys.map(&:to_sym)
14
-
15
- def method_missing(method, *args, &block)
16
- if LOG_LEVEL_METHODS.include?(method)
17
- args[0] = "[knapsack_pro] #{args[0]}"
18
- end
19
- logger.send(method, *args, &block)
20
- end
21
- end
22
- end
@@ -1,21 +0,0 @@
1
- describe KnapsackPro::LoggerWrapper do
2
- let(:io) { StringIO.new }
3
- let(:logger) { ::Logger.new(io) }
4
- let(:logger_wrapper) { described_class.new(logger) }
5
-
6
- subject { io.string }
7
-
8
- [:debug, :info, :warn, :error, :fatal].each do |log_level|
9
- describe "##{log_level}" do
10
- before { logger_wrapper.public_send(log_level, 'Test message') }
11
-
12
- it { should include "[knapsack_pro] Test message\n" }
13
- end
14
- end
15
-
16
- it 'can set logger level via logger wrapper' do
17
- logger_wrapper.level = ::Logger::INFO
18
-
19
- expect(logger_wrapper.level).to eq 1
20
- end
21
- end