knapsack_pro 2.2.1 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -0
- data/README.md +35 -5
- data/lib/knapsack_pro/client/connection.rb +24 -4
- data/lib/knapsack_pro/config/env.rb +15 -0
- data/lib/knapsack_pro/crypto/branch_encryptor.rb +17 -1
- data/lib/knapsack_pro/test_file_finder.rb +4 -0
- data/lib/knapsack_pro/version.rb +1 -1
- data/spec/fixtures/test_file_list_source_file.txt +6 -0
- data/spec/knapsack_pro/client/connection_spec.rb +143 -39
- data/spec/knapsack_pro/config/env_spec.rb +46 -0
- data/spec/knapsack_pro/test_file_finder_spec.rb +18 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e72536de9d4d9ec4a02e935742375b9d8023522f9c21ac8340a991bfdc7982cb
|
4
|
+
data.tar.gz: b7694088ff854a5579ec160fbb08c3219986a95512c2feea15ac6a359dc7aff5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 408aaada7954066b2a3266897aa9b145ce53f2f7409f99f4c8915e122c5deef0818bc14503da59cab1f20c1376a4b205466089c14eaa8c9cd1943699298f8d86
|
7
|
+
data.tar.gz: 85eef879c155557825347ede8671f1b65d9832a8e8b379e94efaf61573cbd676082d43d6219099a35cad008266ef8e16cd719553397c5b71f775ad0ab76f7e79
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,47 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
### 2.7.0
|
4
|
+
|
5
|
+
* Add support for env var `KNAPSACK_PRO_TEST_FILE_LIST_SOURCE_FILE` to allow accepting file containing test files to run
|
6
|
+
|
7
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/pull/129
|
8
|
+
|
9
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.6.0...v2.7.0
|
10
|
+
|
11
|
+
### 2.6.0
|
12
|
+
|
13
|
+
* Improve logger to show failed requests URL and when retry will happen
|
14
|
+
|
15
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/pull/127
|
16
|
+
|
17
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.5.0...v2.6.0
|
18
|
+
|
19
|
+
### 2.5.0
|
20
|
+
|
21
|
+
* Add production branch to non encryptable branches names
|
22
|
+
|
23
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/pull/126
|
24
|
+
|
25
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.4.0...v2.5.0
|
26
|
+
|
27
|
+
### 2.4.0
|
28
|
+
|
29
|
+
* Update list of non encryptable branches
|
30
|
+
|
31
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/pull/125
|
32
|
+
|
33
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.3.0...v2.4.0
|
34
|
+
|
35
|
+
### 2.3.0
|
36
|
+
|
37
|
+
* When you use Regular Mode then try 6 attempts to connect to the API instead of 3 attempts
|
38
|
+
|
39
|
+
Add `KNAPSACK_PRO_MAX_REQUEST_RETRIES` environment variable to let user define their own number of request retries to the API. It is useful to set it to `0` for [forked repos](https://knapsackpro.com/faq/question/how-to-make-knapsack_pro-works-for-forked-repositories-of-my-project) when you want to rely on Fallback Mode.
|
40
|
+
|
41
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/pull/124
|
42
|
+
|
43
|
+
https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v2.2.1...v2.3.0
|
44
|
+
|
3
45
|
### 2.2.1
|
4
46
|
|
5
47
|
* Improve detection of test file path in test-unit runner for test files with shared examples
|
data/README.md
CHANGED
@@ -2320,11 +2320,19 @@ There are a few ways to reproduce tests executed on CI node in your development
|
|
2320
2320
|
|
2321
2321
|
##### for knapsack_pro regular mode
|
2322
2322
|
|
2323
|
-
knapsack_pro gem will retry requests to Knapsack Pro API multiple times every few seconds
|
2323
|
+
knapsack_pro gem will retry requests to Knapsack Pro API multiple times every few seconds till it switches to fallback behavior (Fallback Mode) and it will split test files across CI nodes based on popular test directory names. When knapsack_pro starts Fallback Mode then you will see a warning in the output.
|
2324
|
+
|
2325
|
+
Note there is an unlikely scenario when some of the CI nodes may start in Fallback Mode but others don't and then it could happen that some of test files might be skipped. You should [read this to learn more](https://github.com/KnapsackPro/knapsack_pro-ruby/pull/124) and decide if you like to use Fallback Mode when running tests with knapsack_pro Regular Mode.
|
2326
|
+
|
2327
|
+
If your CI provider allows to retry only one of parallel CI nodes then please [read about this edge case as well](#required-ci-configuration-if-you-use-retry-single-failed-ci-node-feature-on-your-ci-server-when-knapsack_pro_fixed_queue_splittrue-in-queue-mode-or-knapsack_pro_fixed_test_suite_splittrue-in-regular-mode).
|
2324
2328
|
|
2325
2329
|
##### for knapsack_pro queue mode
|
2326
2330
|
|
2327
|
-
knapsack_pro gem will retry requests to Knapsack Pro API multiple times every few seconds till it switches to fallback behavior and it will split test files across CI nodes based on popular test directory names.
|
2331
|
+
knapsack_pro gem will retry requests to Knapsack Pro API multiple times every few seconds till it switches to fallback behavior (Fallback Mode) and it will split test files across CI nodes based on popular test directory names.
|
2332
|
+
|
2333
|
+
Note that if one of the CI nodes loses connection to Knapsack Pro API but others don't, then some of the test files may be executed on multiple CI nodes. **Fallback Mode guarantees each of the test files is run at least once across CI nodes when you use knapsack_pro in Queue Mode.** Thanks to that we know if the whole test suite is green or not. When knapsack_pro starts Fallback Mode then you will see a warning in the output.
|
2334
|
+
|
2335
|
+
If your CI provider allows to retry only one of parallel CI nodes then please [read about this edge case as well](#required-ci-configuration-if-you-use-retry-single-failed-ci-node-feature-on-your-ci-server-when-knapsack_pro_fixed_queue_splittrue-in-queue-mode-or-knapsack_pro_fixed_test_suite_splittrue-in-regular-mode).
|
2328
2336
|
|
2329
2337
|
#### How can I change log level?
|
2330
2338
|
|
@@ -2464,12 +2472,13 @@ Below example is for rspec. You can change `$KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC
|
|
2464
2472
|
if [ "$KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC" = "" ]; then
|
2465
2473
|
KNAPSACK_PRO_ENDPOINT=https://api-disabled-for-fork.knapsackpro.com \
|
2466
2474
|
KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC=disabled-for-fork \
|
2475
|
+
KNAPSACK_PRO_MAX_REQUEST_RETRIES=0 \
|
2467
2476
|
bundle exec rake knapsack_pro:rspec # use Regular Mode here always
|
2468
2477
|
else
|
2469
2478
|
# Regular Mode
|
2470
2479
|
bundle exec rake knapsack_pro:rspec
|
2471
2480
|
|
2472
|
-
#
|
2481
|
+
# or you can use Queue Mode instead of Regular Mode if you like
|
2473
2482
|
# bundle exec rake knapsack_pro:queue:rspec
|
2474
2483
|
fi
|
2475
2484
|
```
|
@@ -3073,7 +3082,9 @@ The test file pattern and exclude pattern support any glob pattern handled by [`
|
|
3073
3082
|
|
3074
3083
|
#### How to run a specific list of test files or only some tests from test file?
|
3075
3084
|
|
3076
|
-
:information_source: If you don't want to use the pattern [`KNAPSACK_PRO_TEST_FILE_PATTERN`](#how-can-i-run-tests-from-multiple-directories) to define a list of tests to run then read below.
|
3085
|
+
:information_source: If you don't want to use the pattern [`KNAPSACK_PRO_TEST_FILE_PATTERN`](#how-can-i-run-tests-from-multiple-directories) to define a list of tests to run then read below two options.
|
3086
|
+
|
3087
|
+
**Option 1:**
|
3077
3088
|
|
3078
3089
|
If you want to run a specific list of test files that are explicitly defined by you or auto-generated by some kind of script you created then please use:
|
3079
3090
|
|
@@ -3081,7 +3092,24 @@ If you want to run a specific list of test files that are explicitly defined by
|
|
3081
3092
|
|
3082
3093
|
Note `KNAPSACK_PRO_TEST_FILE_LIST` must be a list of test files comma separated. You can provide line number for tests inside of spec file in case of RSpec (this way you can run only one test or a group of tests from RSpec spec file). You can provide the same file a few times with different test line number.
|
3083
3094
|
|
3084
|
-
|
3095
|
+
**Option 2:**
|
3096
|
+
|
3097
|
+
Similarly, you can also provide a source file containing the test files that you would like to run. For example:
|
3098
|
+
`KNAPSACK_PRO_TEST_FILE_LIST_SOURCE_FILE=spec/fixtures/test_file_list_source_file.txt`
|
3099
|
+
And the content of the source file can be any of the format below:
|
3100
|
+
|
3101
|
+
```
|
3102
|
+
./spec/test1_spec.rb
|
3103
|
+
spec/test2_spec.rb[1]
|
3104
|
+
./spec/test3_spec.rb[1:2:3:4]
|
3105
|
+
./spec/test4_spec.rb:4
|
3106
|
+
./spec/test4_spec.rb:5
|
3107
|
+
```
|
3108
|
+
|
3109
|
+
> Note that each of the line must be ending with `\n` the new line.
|
3110
|
+
|
3111
|
+
Note when you set `KNAPSACK_PRO_TEST_FILE_LIST` or `KNAPSACK_PRO_TEST_FILE_LIST_SOURCE_FILE` then below environment variables are ignored:
|
3112
|
+
|
3085
3113
|
* `KNAPSACK_PRO_TEST_FILE_PATTERN`
|
3086
3114
|
* `KNAPSACK_PRO_TEST_FILE_EXCLUDE_PATTERN`
|
3087
3115
|
|
@@ -3249,6 +3277,8 @@ $ gem build knapsack_pro.gemspec
|
|
3249
3277
|
$ gem push knapsack_pro-X.X.X.gem
|
3250
3278
|
```
|
3251
3279
|
|
3280
|
+
Update the latest available gem version in `TestSuiteClientVersionChecker` for the Knapsack Pro API repository.
|
3281
|
+
|
3252
3282
|
## Mentions
|
3253
3283
|
|
3254
3284
|
List of articles where people mentioned Knapsack Pro:
|
@@ -4,7 +4,6 @@ module KnapsackPro
|
|
4
4
|
class ServerError < StandardError; end
|
5
5
|
|
6
6
|
TIMEOUT = 15
|
7
|
-
MAX_RETRY = -> { KnapsackPro::Config::Env.fallback_mode_enabled? ? 3 : 6 }
|
8
7
|
REQUEST_RETRY_TIMEBOX = 8
|
9
8
|
|
10
9
|
def initialize(action)
|
@@ -116,14 +115,19 @@ module KnapsackPro
|
|
116
115
|
|
117
116
|
response_body
|
118
117
|
rescue ServerError, Errno::ECONNREFUSED, Errno::ETIMEDOUT, Errno::EPIPE, EOFError, SocketError, Net::OpenTimeout, Net::ReadTimeout, OpenSSL::SSL::SSLError => e
|
118
|
+
logger.warn("#{action.http_method.to_s.upcase} #{endpoint_url}")
|
119
|
+
logger.warn('Request failed due to:')
|
119
120
|
logger.warn(e.inspect)
|
120
121
|
retries += 1
|
121
|
-
if retries <
|
122
|
+
if retries < max_request_retries
|
122
123
|
wait = retries * REQUEST_RETRY_TIMEBOX
|
123
|
-
logger.warn("Wait #{wait}s and retry request to Knapsack Pro API.")
|
124
124
|
print_every = 2 # seconds
|
125
125
|
(wait / print_every).ceil.times do |i|
|
126
|
-
|
126
|
+
if i == 0
|
127
|
+
logger.warn("Wait for #{wait}s before retrying the request to Knapsack Pro API.")
|
128
|
+
else
|
129
|
+
logger.warn("#{wait - i * print_every}s left before retry...")
|
130
|
+
end
|
127
131
|
Kernel.sleep(print_every)
|
128
132
|
end
|
129
133
|
retry
|
@@ -156,6 +160,22 @@ module KnapsackPro
|
|
156
160
|
http.get(uri, json_headers)
|
157
161
|
end
|
158
162
|
end
|
163
|
+
|
164
|
+
def max_request_retries
|
165
|
+
# when user defined max request retries
|
166
|
+
return KnapsackPro::Config::Env.max_request_retries if KnapsackPro::Config::Env.max_request_retries
|
167
|
+
|
168
|
+
# when Fallback Mode is disabled then try more attempts to connect to the API
|
169
|
+
return 6 unless KnapsackPro::Config::Env.fallback_mode_enabled?
|
170
|
+
|
171
|
+
# when Regular Mode then try more attempts to connect to the API
|
172
|
+
# if only one CI node starts Fallback Mode instead of all then we can't guarantee all test files will be run
|
173
|
+
# https://github.com/KnapsackPro/knapsack_pro-ruby/pull/124
|
174
|
+
return 6 if KnapsackPro::Config::Env.regular_mode?
|
175
|
+
|
176
|
+
# default number of attempts
|
177
|
+
3
|
178
|
+
end
|
159
179
|
end
|
160
180
|
end
|
161
181
|
end
|
@@ -36,6 +36,13 @@ module KnapsackPro
|
|
36
36
|
).to_i
|
37
37
|
end
|
38
38
|
|
39
|
+
def max_request_retries
|
40
|
+
number = ENV['KNAPSACK_PRO_MAX_REQUEST_RETRIES']
|
41
|
+
if number
|
42
|
+
number.to_i
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
39
46
|
def commit_hash
|
40
47
|
ENV['KNAPSACK_PRO_COMMIT_HASH'] ||
|
41
48
|
ci_env_for(:commit_hash)
|
@@ -67,6 +74,10 @@ module KnapsackPro
|
|
67
74
|
ENV['KNAPSACK_PRO_TEST_FILE_LIST']
|
68
75
|
end
|
69
76
|
|
77
|
+
def test_file_list_source_file
|
78
|
+
ENV['KNAPSACK_PRO_TEST_FILE_LIST_SOURCE_FILE']
|
79
|
+
end
|
80
|
+
|
70
81
|
def test_dir
|
71
82
|
ENV['KNAPSACK_PRO_TEST_DIR']
|
72
83
|
end
|
@@ -83,6 +94,10 @@ module KnapsackPro
|
|
83
94
|
recording_enabled == 'true'
|
84
95
|
end
|
85
96
|
|
97
|
+
def regular_mode?
|
98
|
+
recording_enabled?
|
99
|
+
end
|
100
|
+
|
86
101
|
def queue_recording_enabled
|
87
102
|
ENV['KNAPSACK_PRO_QUEUE_RECORDING_ENABLED']
|
88
103
|
end
|
@@ -1,7 +1,23 @@
|
|
1
1
|
module KnapsackPro
|
2
2
|
module Crypto
|
3
3
|
class BranchEncryptor
|
4
|
-
NON_ENCRYPTABLE_BRANCHES =
|
4
|
+
NON_ENCRYPTABLE_BRANCHES = [
|
5
|
+
'master',
|
6
|
+
'main',
|
7
|
+
'develop',
|
8
|
+
'development',
|
9
|
+
'dev',
|
10
|
+
'staging',
|
11
|
+
'production',
|
12
|
+
# GitHub Actions has branch names starting with refs/heads/
|
13
|
+
'refs/heads/master',
|
14
|
+
'refs/heads/main',
|
15
|
+
'refs/heads/develop',
|
16
|
+
'refs/heads/development',
|
17
|
+
'refs/heads/dev',
|
18
|
+
'refs/heads/staging',
|
19
|
+
'refs/heads/production',
|
20
|
+
]
|
5
21
|
|
6
22
|
def self.call(branch)
|
7
23
|
if KnapsackPro::Config::Env.branch_encrypted?
|
@@ -63,6 +63,10 @@ module KnapsackPro
|
|
63
63
|
return KnapsackPro::Config::Env.test_file_list.split(',').map(&:strip)
|
64
64
|
end
|
65
65
|
|
66
|
+
if test_file_list_enabled && KnapsackPro::Config::Env.test_file_list_source_file
|
67
|
+
return File.read(KnapsackPro::Config::Env.test_file_list_source_file).split(/\n/)
|
68
|
+
end
|
69
|
+
|
66
70
|
test_file_paths = Dir.glob(test_file_pattern).uniq
|
67
71
|
|
68
72
|
excluded_test_file_paths =
|
data/lib/knapsack_pro/version.rb
CHANGED
@@ -84,22 +84,22 @@ shared_examples 'when retry request' do
|
|
84
84
|
expect(logger).to receive(:error).exactly(3).with(parsed_response)
|
85
85
|
|
86
86
|
server_error = described_class::ServerError.new(parsed_response)
|
87
|
+
expect(logger).to receive(:warn).exactly(3).with("#{expected_http_method} http://api.knapsackpro.test:3000/v1/fake_endpoint")
|
88
|
+
expect(logger).to receive(:warn).exactly(3).with('Request failed due to:')
|
87
89
|
expect(logger).to receive(:warn).exactly(3).with(server_error.inspect)
|
88
90
|
|
89
|
-
expect(logger).to receive(:warn).with("Wait 8s
|
90
|
-
expect(logger).to receive(:warn).with("
|
91
|
-
expect(logger).to receive(:warn).with("
|
92
|
-
expect(logger).to receive(:warn).with("
|
93
|
-
expect(logger).to receive(:warn).with("
|
94
|
-
expect(logger).to receive(:warn).with("
|
95
|
-
expect(logger).to receive(:warn).with("
|
96
|
-
expect(logger).to receive(:warn).with("
|
97
|
-
expect(logger).to receive(:warn).with("
|
98
|
-
expect(logger).to receive(:warn).with("
|
99
|
-
expect(logger).to receive(:warn).with("
|
100
|
-
expect(logger).to receive(:warn).with("
|
101
|
-
expect(logger).to receive(:warn).with("Next request in 4s...")
|
102
|
-
expect(logger).to receive(:warn).with("Next request in 2s...")
|
91
|
+
expect(logger).to receive(:warn).with("Wait for 8s before retrying the request to Knapsack Pro API.")
|
92
|
+
expect(logger).to receive(:warn).with("6s left before retry...")
|
93
|
+
expect(logger).to receive(:warn).with("4s left before retry...")
|
94
|
+
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.")
|
96
|
+
expect(logger).to receive(:warn).with("14s left before retry...")
|
97
|
+
expect(logger).to receive(:warn).with("12s left before retry...")
|
98
|
+
expect(logger).to receive(:warn).with("10s left before retry...")
|
99
|
+
expect(logger).to receive(:warn).with("8s left before retry...")
|
100
|
+
expect(logger).to receive(:warn).with("6s left before retry...")
|
101
|
+
expect(logger).to receive(:warn).with("4s left before retry...")
|
102
|
+
expect(logger).to receive(:warn).with("2s left before retry...")
|
103
103
|
expect(Kernel).to receive(:sleep).exactly(12).with(2)
|
104
104
|
|
105
105
|
expect(subject).to eq(parsed_response)
|
@@ -108,6 +108,53 @@ shared_examples 'when retry request' do
|
|
108
108
|
expect(connection.errors?).to be true
|
109
109
|
end
|
110
110
|
|
111
|
+
context 'when max request retries defined' do
|
112
|
+
before do
|
113
|
+
expect(KnapsackPro::Config::Env).to receive(:max_request_retries).at_least(1).and_return(4)
|
114
|
+
end
|
115
|
+
|
116
|
+
it do
|
117
|
+
expect(logger).to receive(:debug).exactly(4).with("#{expected_http_method} http://api.knapsackpro.test:3000/v1/fake_endpoint")
|
118
|
+
expect(logger).to receive(:debug).exactly(4).with('API request UUID: fake-uuid')
|
119
|
+
expect(logger).to receive(:debug).exactly(4).with('API response:')
|
120
|
+
|
121
|
+
parsed_response = { 'error' => 'Internal Server Error' }
|
122
|
+
|
123
|
+
expect(logger).to receive(:error).exactly(4).with(parsed_response)
|
124
|
+
|
125
|
+
server_error = described_class::ServerError.new(parsed_response)
|
126
|
+
expect(logger).to receive(:warn).exactly(4).with("#{expected_http_method} http://api.knapsackpro.test:3000/v1/fake_endpoint")
|
127
|
+
expect(logger).to receive(:warn).exactly(4).with('Request failed due to:')
|
128
|
+
expect(logger).to receive(:warn).exactly(4).with(server_error.inspect)
|
129
|
+
|
130
|
+
expect(logger).to receive(:warn).with("Wait for 8s before retrying the request to Knapsack Pro API.")
|
131
|
+
expect(logger).to receive(:warn).with("6s left before retry...")
|
132
|
+
expect(logger).to receive(:warn).with("4s left before retry...")
|
133
|
+
expect(logger).to receive(:warn).with("2s left before retry...")
|
134
|
+
|
135
|
+
expect(logger).to receive(:warn).with("Wait for 16s before retrying the request to Knapsack Pro API.")
|
136
|
+
expect(logger).to receive(:warn).with("14s left before retry...")
|
137
|
+
expect(logger).to receive(:warn).with("12s left before retry...")
|
138
|
+
expect(logger).to receive(:warn).with("10s left before retry...")
|
139
|
+
expect(logger).to receive(:warn).with("8s left before retry...")
|
140
|
+
expect(logger).to receive(:warn).with("6s left before retry...")
|
141
|
+
expect(logger).to receive(:warn).with("4s left before retry...")
|
142
|
+
expect(logger).to receive(:warn).with("2s left before retry...")
|
143
|
+
|
144
|
+
expect(logger).to receive(:warn).with("Wait for 24s before retrying the request to Knapsack Pro API.")
|
145
|
+
11.times do |i|
|
146
|
+
expect(logger).to receive(:warn).with("#{(i+1)*2}s left before retry...")
|
147
|
+
end
|
148
|
+
|
149
|
+
expect(Kernel).to receive(:sleep).exactly(4+8+12).with(2)
|
150
|
+
|
151
|
+
expect(subject).to eq(parsed_response)
|
152
|
+
|
153
|
+
expect(connection.success?).to be false
|
154
|
+
expect(connection.errors?).to be true
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
111
158
|
context 'when Fallback Mode is disabled' do
|
112
159
|
before do
|
113
160
|
expect(KnapsackPro::Config::Env).to receive(:fallback_mode_enabled?).at_least(1).and_return(false)
|
@@ -123,37 +170,94 @@ shared_examples 'when retry request' do
|
|
123
170
|
expect(logger).to receive(:error).exactly(6).with(parsed_response)
|
124
171
|
|
125
172
|
server_error = described_class::ServerError.new(parsed_response)
|
173
|
+
expect(logger).to receive(:warn).exactly(6).with("#{expected_http_method} http://api.knapsackpro.test:3000/v1/fake_endpoint")
|
174
|
+
expect(logger).to receive(:warn).exactly(6).with('Request failed due to:')
|
175
|
+
expect(logger).to receive(:warn).exactly(6).with(server_error.inspect)
|
176
|
+
|
177
|
+
expect(logger).to receive(:warn).with("Wait for 8s before retrying the request to Knapsack Pro API.")
|
178
|
+
expect(logger).to receive(:warn).with("6s left before retry...")
|
179
|
+
expect(logger).to receive(:warn).with("4s left before retry...")
|
180
|
+
expect(logger).to receive(:warn).with("2s left before retry...")
|
181
|
+
|
182
|
+
expect(logger).to receive(:warn).with("Wait for 16s before retrying the request to Knapsack Pro API.")
|
183
|
+
expect(logger).to receive(:warn).with("14s left before retry...")
|
184
|
+
expect(logger).to receive(:warn).with("12s left before retry...")
|
185
|
+
expect(logger).to receive(:warn).with("10s left before retry...")
|
186
|
+
expect(logger).to receive(:warn).with("8s left before retry...")
|
187
|
+
expect(logger).to receive(:warn).with("6s left before retry...")
|
188
|
+
expect(logger).to receive(:warn).with("4s left before retry...")
|
189
|
+
expect(logger).to receive(:warn).with("2s left before retry...")
|
190
|
+
|
191
|
+
expect(logger).to receive(:warn).with("Wait for 24s before retrying the request to Knapsack Pro API.")
|
192
|
+
11.times do |i|
|
193
|
+
expect(logger).to receive(:warn).with("#{(i+1)*2}s left before retry...")
|
194
|
+
end
|
195
|
+
|
196
|
+
expect(logger).to receive(:warn).with("Wait for 32s before retrying the request to Knapsack Pro API.")
|
197
|
+
15.times do |i|
|
198
|
+
expect(logger).to receive(:warn).with("#{(i+1)*2}s left before retry...")
|
199
|
+
end
|
200
|
+
|
201
|
+
expect(logger).to receive(:warn).with("Wait for 40s before retrying the request to Knapsack Pro API.")
|
202
|
+
19.times do |i|
|
203
|
+
expect(logger).to receive(:warn).with("#{(i+1)*2}s left before retry...")
|
204
|
+
end
|
205
|
+
|
206
|
+
expect(Kernel).to receive(:sleep).exactly(60).with(2)
|
207
|
+
|
208
|
+
expect(subject).to eq(parsed_response)
|
209
|
+
|
210
|
+
expect(connection.success?).to be false
|
211
|
+
expect(connection.errors?).to be true
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
context 'when Regular Mode' do
|
216
|
+
before do
|
217
|
+
expect(KnapsackPro::Config::Env).to receive(:regular_mode?).at_least(1).and_return(true)
|
218
|
+
end
|
219
|
+
|
220
|
+
it do
|
221
|
+
expect(logger).to receive(:debug).exactly(6).with("#{expected_http_method} http://api.knapsackpro.test:3000/v1/fake_endpoint")
|
222
|
+
expect(logger).to receive(:debug).exactly(6).with('API request UUID: fake-uuid')
|
223
|
+
expect(logger).to receive(:debug).exactly(6).with('API response:')
|
224
|
+
|
225
|
+
parsed_response = { 'error' => 'Internal Server Error' }
|
226
|
+
|
227
|
+
expect(logger).to receive(:error).exactly(6).with(parsed_response)
|
228
|
+
|
229
|
+
server_error = described_class::ServerError.new(parsed_response)
|
230
|
+
expect(logger).to receive(:warn).exactly(6).with("#{expected_http_method} http://api.knapsackpro.test:3000/v1/fake_endpoint")
|
231
|
+
expect(logger).to receive(:warn).exactly(6).with('Request failed due to:')
|
126
232
|
expect(logger).to receive(:warn).exactly(6).with(server_error.inspect)
|
127
233
|
|
128
|
-
expect(logger).to receive(:warn).with("Wait 8s
|
129
|
-
expect(logger).to receive(:warn).with("
|
130
|
-
expect(logger).to receive(:warn).with("
|
131
|
-
expect(logger).to receive(:warn).with("
|
132
|
-
|
133
|
-
|
134
|
-
expect(logger).to receive(:warn).with("
|
135
|
-
expect(logger).to receive(:warn).with("
|
136
|
-
expect(logger).to receive(:warn).with("
|
137
|
-
expect(logger).to receive(:warn).with("
|
138
|
-
expect(logger).to receive(:warn).with("
|
139
|
-
expect(logger).to receive(:warn).with("
|
140
|
-
expect(logger).to receive(:warn).with("
|
141
|
-
|
142
|
-
expect(logger).to receive(:warn).with("
|
143
|
-
|
144
|
-
|
145
|
-
12.times do |i|
|
146
|
-
expect(logger).to receive(:warn).with("Next request in #{(i+1)*2}s...")
|
234
|
+
expect(logger).to receive(:warn).with("Wait for 8s before retrying the request to Knapsack Pro API.")
|
235
|
+
expect(logger).to receive(:warn).with("6s left before retry...")
|
236
|
+
expect(logger).to receive(:warn).with("4s left before retry...")
|
237
|
+
expect(logger).to receive(:warn).with("2s left before retry...")
|
238
|
+
|
239
|
+
expect(logger).to receive(:warn).with("Wait for 16s before retrying the request to Knapsack Pro API.")
|
240
|
+
expect(logger).to receive(:warn).with("14s left before retry...")
|
241
|
+
expect(logger).to receive(:warn).with("12s left before retry...")
|
242
|
+
expect(logger).to receive(:warn).with("10s left before retry...")
|
243
|
+
expect(logger).to receive(:warn).with("8s left before retry...")
|
244
|
+
expect(logger).to receive(:warn).with("6s left before retry...")
|
245
|
+
expect(logger).to receive(:warn).with("4s left before retry...")
|
246
|
+
expect(logger).to receive(:warn).with("2s left before retry...")
|
247
|
+
|
248
|
+
expect(logger).to receive(:warn).with("Wait for 24s before retrying the request to Knapsack Pro API.")
|
249
|
+
11.times do |i|
|
250
|
+
expect(logger).to receive(:warn).with("#{(i+1)*2}s left before retry...")
|
147
251
|
end
|
148
252
|
|
149
|
-
expect(logger).to receive(:warn).with("Wait 32s
|
150
|
-
|
151
|
-
expect(logger).to receive(:warn).with("
|
253
|
+
expect(logger).to receive(:warn).with("Wait for 32s before retrying the request to Knapsack Pro API.")
|
254
|
+
15.times do |i|
|
255
|
+
expect(logger).to receive(:warn).with("#{(i+1)*2}s left before retry...")
|
152
256
|
end
|
153
257
|
|
154
|
-
expect(logger).to receive(:warn).with("Wait 40s
|
155
|
-
|
156
|
-
expect(logger).to receive(:warn).with("
|
258
|
+
expect(logger).to receive(:warn).with("Wait for 40s before retrying the request to Knapsack Pro API.")
|
259
|
+
19.times do |i|
|
260
|
+
expect(logger).to receive(:warn).with("#{(i+1)*2}s left before retry...")
|
157
261
|
end
|
158
262
|
|
159
263
|
expect(Kernel).to receive(:sleep).exactly(60).with(2)
|
@@ -100,6 +100,19 @@ describe KnapsackPro::Config::Env do
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
|
+
describe '.max_request_retries' do
|
104
|
+
subject { described_class.max_request_retries }
|
105
|
+
|
106
|
+
context 'when ENV exists' do
|
107
|
+
before { stub_const("ENV", { 'KNAPSACK_PRO_MAX_REQUEST_RETRIES' => '2' }) }
|
108
|
+
it { should eq 2 }
|
109
|
+
end
|
110
|
+
|
111
|
+
context "when ENV doesn't exist" do
|
112
|
+
it { should be_nil }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
103
116
|
describe '.commit_hash' do
|
104
117
|
subject { described_class.commit_hash }
|
105
118
|
|
@@ -225,6 +238,20 @@ describe KnapsackPro::Config::Env do
|
|
225
238
|
end
|
226
239
|
end
|
227
240
|
|
241
|
+
describe '.test_file_list_source_file' do
|
242
|
+
subject { described_class.test_file_list_source_file }
|
243
|
+
|
244
|
+
context 'when ENV exists' do
|
245
|
+
let(:test_file_list_source_file) { 'spec/fixtures/test_file_list_source_file.txt' }
|
246
|
+
before { stub_const("ENV", { 'KNAPSACK_PRO_TEST_FILE_LIST_SOURCE_FILE' => test_file_list_source_file }) }
|
247
|
+
it { should eq test_file_list_source_file }
|
248
|
+
end
|
249
|
+
|
250
|
+
context "when ENV doesn't exist" do
|
251
|
+
it { should be_nil }
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
228
255
|
describe '.test_dir' do
|
229
256
|
subject { described_class.test_dir }
|
230
257
|
|
@@ -267,6 +294,25 @@ describe KnapsackPro::Config::Env do
|
|
267
294
|
end
|
268
295
|
end
|
269
296
|
|
297
|
+
|
298
|
+
describe '.regular_mode?' do
|
299
|
+
subject { described_class.regular_mode? }
|
300
|
+
|
301
|
+
before do
|
302
|
+
expect(described_class).to receive(:recording_enabled?).and_return(recording_enabled)
|
303
|
+
end
|
304
|
+
|
305
|
+
context 'when recording is enabled' do
|
306
|
+
let(:recording_enabled) { true }
|
307
|
+
it { should be true }
|
308
|
+
end
|
309
|
+
|
310
|
+
context 'when recording is not enabled' do
|
311
|
+
let(:recording_enabled) { false }
|
312
|
+
it { should be false }
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
270
316
|
describe '.recording_enabled?' do
|
271
317
|
subject { described_class.recording_enabled? }
|
272
318
|
|
@@ -154,5 +154,23 @@ describe KnapsackPro::TestFileFinder do
|
|
154
154
|
end
|
155
155
|
end
|
156
156
|
end
|
157
|
+
|
158
|
+
context 'when KNAPSACK_PRO_TEST_FILE_LIST_SOURCE_FILE is defined' do
|
159
|
+
let(:test_file_list_source_file) { 'spec/fixtures/test_file_list_source_file.txt' }
|
160
|
+
|
161
|
+
before do
|
162
|
+
stub_const("ENV", { 'KNAPSACK_PRO_TEST_FILE_LIST_SOURCE_FILE' => test_file_list_source_file })
|
163
|
+
end
|
164
|
+
|
165
|
+
it do
|
166
|
+
expect(subject).to eq([
|
167
|
+
{ 'path' => 'spec/test1_spec.rb' },
|
168
|
+
{ 'path' => 'spec/test2_spec.rb[1]' },
|
169
|
+
{ 'path' => 'spec/test3_spec.rb[1:2:3:4]' },
|
170
|
+
{ 'path' => 'spec/test4_spec.rb:4' },
|
171
|
+
{ 'path' => 'spec/test4_spec.rb:5' },
|
172
|
+
])
|
173
|
+
end
|
174
|
+
end
|
157
175
|
end
|
158
176
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knapsack_pro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ArturT
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -308,6 +308,7 @@ files:
|
|
308
308
|
- lib/tasks/salt.rake
|
309
309
|
- lib/tasks/spinach.rake
|
310
310
|
- lib/tasks/test_unit.rake
|
311
|
+
- spec/fixtures/test_file_list_source_file.txt
|
311
312
|
- spec/fixtures/vcr_cassettes/api/v1/build_distributions/subset/invalid_test_suite_token.yml
|
312
313
|
- spec/fixtures/vcr_cassettes/api/v1/build_distributions/subset/success.yml
|
313
314
|
- spec/fixtures/vcr_cassettes/api/v1/build_subsets/create/invalid_test_suite_token.yml
|
@@ -428,6 +429,7 @@ specification_version: 4
|
|
428
429
|
summary: Knapsack Pro splits tests across parallel CI nodes and ensures each parallel
|
429
430
|
job finish work at a similar time.
|
430
431
|
test_files:
|
432
|
+
- spec/fixtures/test_file_list_source_file.txt
|
431
433
|
- spec/fixtures/vcr_cassettes/api/v1/build_distributions/subset/invalid_test_suite_token.yml
|
432
434
|
- spec/fixtures/vcr_cassettes/api/v1/build_distributions/subset/success.yml
|
433
435
|
- spec/fixtures/vcr_cassettes/api/v1/build_subsets/create/invalid_test_suite_token.yml
|