knapsack_pro 8.0.2 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -1
- data/lib/knapsack_pro/base_allocator_builder.rb +2 -46
- data/lib/knapsack_pro/crypto/decryptor.rb +4 -7
- data/lib/knapsack_pro/queue_allocator.rb +99 -47
- data/lib/knapsack_pro/queue_allocator_builder.rb +1 -2
- data/lib/knapsack_pro/{allocator.rb → regular_allocator.rb} +97 -48
- data/lib/knapsack_pro/{allocator_builder.rb → regular_allocator_builder.rb} +3 -4
- data/lib/knapsack_pro/runners/base_runner.rb +1 -1
- data/lib/knapsack_pro/test_suite.rb +63 -0
- data/lib/knapsack_pro/version.rb +1 -1
- data/lib/knapsack_pro.rb +3 -2
- data/spec/integration/runners/queue/rspec_runner_spec.rb +0 -4
- data/spec/knapsack_pro/base_allocator_builder_spec.rb +0 -102
- data/spec/knapsack_pro/crypto/decryptor_spec.rb +3 -1
- data/spec/knapsack_pro/runners/base_runner_spec.rb +3 -3
- metadata +4 -11
- data/spec/knapsack_pro/allocator_builder_spec.rb +0 -36
- data/spec/knapsack_pro/allocator_spec.rb +0 -233
- data/spec/knapsack_pro/queue_allocator_builder_spec.rb +0 -39
- data/spec/knapsack_pro/queue_allocator_spec.rb +0 -304
@@ -1,304 +0,0 @@
|
|
1
|
-
describe KnapsackPro::QueueAllocator do
|
2
|
-
let(:fast_and_slow_test_files_to_run) { double }
|
3
|
-
let(:fallback_mode_test_files) { double }
|
4
|
-
let(:ci_node_total) { double }
|
5
|
-
let(:ci_node_index) { double }
|
6
|
-
let(:ci_node_build_id) { double }
|
7
|
-
let(:repository_adapter) { instance_double(KnapsackPro::RepositoryAdapters::EnvAdapter, commit_hash: double, branch: double) }
|
8
|
-
|
9
|
-
let(:queue_allocator) do
|
10
|
-
described_class.new(
|
11
|
-
fast_and_slow_test_files_to_run: fast_and_slow_test_files_to_run,
|
12
|
-
fallback_mode_test_files: fallback_mode_test_files,
|
13
|
-
ci_node_total: ci_node_total,
|
14
|
-
ci_node_index: ci_node_index,
|
15
|
-
ci_node_build_id: ci_node_build_id,
|
16
|
-
repository_adapter: repository_adapter
|
17
|
-
)
|
18
|
-
end
|
19
|
-
|
20
|
-
describe '#test_file_paths' do
|
21
|
-
let(:executed_test_files) { [] }
|
22
|
-
let(:response) { double }
|
23
|
-
let(:api_code) { nil }
|
24
|
-
|
25
|
-
subject { queue_allocator.test_file_paths(can_initialize_queue, executed_test_files) }
|
26
|
-
|
27
|
-
shared_examples_for 'when connection to API failed (fallback mode)' do
|
28
|
-
context 'when fallback mode is disabled' do
|
29
|
-
before do
|
30
|
-
expect(KnapsackPro::Config::Env).to receive(:fallback_mode_enabled?).and_return(false)
|
31
|
-
end
|
32
|
-
|
33
|
-
it do
|
34
|
-
expect { subject }.to raise_error(KnapsackPro::QueueAllocator::FallbackModeError, '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')
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
context 'when CI node retry count > 0' do
|
39
|
-
before do
|
40
|
-
expect(KnapsackPro::Config::Env).to receive(:ci_node_retry_count).and_return(1)
|
41
|
-
end
|
42
|
-
|
43
|
-
context 'when fixed_queue_split=true' do
|
44
|
-
before do
|
45
|
-
expect(KnapsackPro::Config::Env).to receive(:fixed_queue_split).and_return(true)
|
46
|
-
end
|
47
|
-
|
48
|
-
it do
|
49
|
-
expect { subject }.to raise_error(KnapsackPro::QueueAllocator::FallbackModeError, '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')
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
context 'when fixed_queue_split=false' do
|
54
|
-
before do
|
55
|
-
expect(KnapsackPro::Config::Env).to receive(:fixed_queue_split).and_return(false)
|
56
|
-
end
|
57
|
-
|
58
|
-
it do
|
59
|
-
expect { subject }.to raise_error(KnapsackPro::QueueAllocator::FallbackModeError, '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 Please ensure you have set KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true to allow Knapsack Pro API remember the recorded CI node tests so when you retry failed tests on the CI node then the same set of tests will be executed. See more https://knapsackpro.com/perma/ruby/fixed-queue-split')
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
context 'when fallback mode started' do
|
65
|
-
before do
|
66
|
-
test_flat_distributor = instance_double(KnapsackPro::TestFlatDistributor)
|
67
|
-
expect(KnapsackPro::TestFlatDistributor).to receive(:new).with(fallback_mode_test_files, ci_node_total).and_return(test_flat_distributor)
|
68
|
-
expect(test_flat_distributor).to receive(:test_files_for_node).with(ci_node_index).and_return([
|
69
|
-
{ 'path' => 'c_spec.rb' },
|
70
|
-
{ 'path' => 'd_spec.rb' },
|
71
|
-
])
|
72
|
-
end
|
73
|
-
|
74
|
-
context 'when no test files were executed yet' do
|
75
|
-
let(:executed_test_files) { [] }
|
76
|
-
|
77
|
-
it 'enables fallback mode and returns fallback test files' do
|
78
|
-
expect(subject).to eq ['c_spec.rb', 'd_spec.rb']
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
context 'when test files were already executed' do
|
83
|
-
let(:executed_test_files) { ['c_spec.rb', 'additional_executed_spec.rb'] }
|
84
|
-
|
85
|
-
it 'enables fallback mode and returns fallback test files' do
|
86
|
-
expect(subject).to eq ['d_spec.rb']
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context 'when can_initialize_queue=true' do
|
93
|
-
let(:can_initialize_queue) { true }
|
94
|
-
|
95
|
-
before do
|
96
|
-
encrypted_branch = double
|
97
|
-
expect(KnapsackPro::Crypto::BranchEncryptor).to receive(:call).with(repository_adapter.branch).and_return(encrypted_branch)
|
98
|
-
|
99
|
-
action = double
|
100
|
-
expect(KnapsackPro::Client::API::V1::Queues).to receive(:queue).with(
|
101
|
-
can_initialize_queue: can_initialize_queue,
|
102
|
-
attempt_connect_to_queue: true, # when can_initialize_queue=true then expect attempt_connect_to_queue=true
|
103
|
-
commit_hash: repository_adapter.commit_hash,
|
104
|
-
branch: encrypted_branch,
|
105
|
-
node_total: ci_node_total,
|
106
|
-
node_index: ci_node_index,
|
107
|
-
node_build_id: ci_node_build_id,
|
108
|
-
test_files: nil, # when attempt_connect_to_queue=true then expect test_files is nil to make fast request to API
|
109
|
-
).and_return(action)
|
110
|
-
|
111
|
-
connection = instance_double(KnapsackPro::Client::Connection,
|
112
|
-
call: response,
|
113
|
-
success?: success?,
|
114
|
-
errors?: errors?,
|
115
|
-
api_code: api_code)
|
116
|
-
expect(KnapsackPro::Client::Connection).to receive(:new).with(action).and_return(connection)
|
117
|
-
end
|
118
|
-
|
119
|
-
context 'when successful request to API' do
|
120
|
-
let(:success?) { true }
|
121
|
-
|
122
|
-
context 'when response has errors' do
|
123
|
-
let(:errors?) { true }
|
124
|
-
|
125
|
-
it do
|
126
|
-
expect { subject }.to raise_error(ArgumentError)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
context 'when response has no errors' do
|
131
|
-
let(:errors?) { false }
|
132
|
-
|
133
|
-
context 'when response returns test files (successful attempt to connect to queue already existing on the API side)' do
|
134
|
-
let(:response) do
|
135
|
-
{
|
136
|
-
'test_files' => [
|
137
|
-
{ 'path' => 'a_spec.rb' },
|
138
|
-
{ 'path' => 'b_spec.rb' },
|
139
|
-
]
|
140
|
-
}
|
141
|
-
end
|
142
|
-
|
143
|
-
before do
|
144
|
-
expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(fast_and_slow_test_files_to_run, response['test_files']).and_call_original
|
145
|
-
end
|
146
|
-
|
147
|
-
it { should eq ['a_spec.rb', 'b_spec.rb'] }
|
148
|
-
end
|
149
|
-
|
150
|
-
context 'when the response has the API code=ATTEMPT_CONNECT_TO_QUEUE_FAILED' do
|
151
|
-
let(:api_code) { 'ATTEMPT_CONNECT_TO_QUEUE_FAILED' }
|
152
|
-
|
153
|
-
before do
|
154
|
-
encrypted_branch = double
|
155
|
-
expect(KnapsackPro::Crypto::BranchEncryptor).to receive(:call).with(repository_adapter.branch).and_return(encrypted_branch)
|
156
|
-
|
157
|
-
encrypted_test_files = double
|
158
|
-
expect(KnapsackPro::Crypto::Encryptor).to receive(:call).with(fast_and_slow_test_files_to_run).and_return(encrypted_test_files)
|
159
|
-
|
160
|
-
# 2nd request is no more an attempt to connect to queue.
|
161
|
-
# We want to try to initalize a new queue so we will also send list of test files from disk.
|
162
|
-
action = double
|
163
|
-
expect(KnapsackPro::Client::API::V1::Queues).to receive(:queue).with(
|
164
|
-
can_initialize_queue: can_initialize_queue,
|
165
|
-
attempt_connect_to_queue: false,
|
166
|
-
commit_hash: repository_adapter.commit_hash,
|
167
|
-
branch: encrypted_branch,
|
168
|
-
node_total: ci_node_total,
|
169
|
-
node_index: ci_node_index,
|
170
|
-
node_build_id: ci_node_build_id,
|
171
|
-
test_files: encrypted_test_files,
|
172
|
-
).and_return(action)
|
173
|
-
|
174
|
-
connection = instance_double(KnapsackPro::Client::Connection,
|
175
|
-
call: response2,
|
176
|
-
success?: response2_success?,
|
177
|
-
errors?: response2_errors?,
|
178
|
-
api_code: nil)
|
179
|
-
expect(KnapsackPro::Client::Connection).to receive(:new).with(action).and_return(connection)
|
180
|
-
end
|
181
|
-
|
182
|
-
context 'when successful 2nd request to API' do
|
183
|
-
let(:response2_success?) { true }
|
184
|
-
|
185
|
-
context 'when 2nd response has errors' do
|
186
|
-
let(:response2_errors?) { true }
|
187
|
-
let(:response2) { nil }
|
188
|
-
|
189
|
-
it do
|
190
|
-
expect { subject }.to raise_error(ArgumentError)
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
context 'when 2nd response has no errors' do
|
195
|
-
let(:response2_errors?) { false }
|
196
|
-
|
197
|
-
context 'when 2nd response returns test files (successfully initialized a new queue or connected to an existing queue on the API side)' do
|
198
|
-
let(:response2) do
|
199
|
-
{
|
200
|
-
'test_files' => [
|
201
|
-
{ 'path' => 'a_spec.rb' },
|
202
|
-
{ 'path' => 'b_spec.rb' },
|
203
|
-
]
|
204
|
-
}
|
205
|
-
end
|
206
|
-
|
207
|
-
before do
|
208
|
-
expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(fast_and_slow_test_files_to_run, response2['test_files']).and_call_original
|
209
|
-
end
|
210
|
-
|
211
|
-
it { should eq ['a_spec.rb', 'b_spec.rb'] }
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
context 'when not successful 2nd request to API' do
|
217
|
-
let(:response2_success?) { false }
|
218
|
-
let(:response2_errors?) { false }
|
219
|
-
let(:response2) { nil }
|
220
|
-
|
221
|
-
it_behaves_like 'when connection to API failed (fallback mode)'
|
222
|
-
end
|
223
|
-
end
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
context 'when not successful request to API' do
|
228
|
-
let(:success?) { false }
|
229
|
-
let(:errors?) { false }
|
230
|
-
|
231
|
-
it_behaves_like 'when connection to API failed (fallback mode)'
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
context 'when can_initialize_queue=false' do
|
236
|
-
let(:can_initialize_queue) { false }
|
237
|
-
let(:api_code) { nil }
|
238
|
-
|
239
|
-
before do
|
240
|
-
encrypted_branch = double
|
241
|
-
expect(KnapsackPro::Crypto::BranchEncryptor).to receive(:call).with(repository_adapter.branch).and_return(encrypted_branch)
|
242
|
-
|
243
|
-
action = double
|
244
|
-
expect(KnapsackPro::Client::API::V1::Queues).to receive(:queue).with(
|
245
|
-
can_initialize_queue: can_initialize_queue,
|
246
|
-
attempt_connect_to_queue: false, # when can_initialize_queue=false then expect attempt_connect_to_queue=false
|
247
|
-
commit_hash: repository_adapter.commit_hash,
|
248
|
-
branch: encrypted_branch,
|
249
|
-
node_total: ci_node_total,
|
250
|
-
node_index: ci_node_index,
|
251
|
-
node_build_id: ci_node_build_id,
|
252
|
-
test_files: nil, # when can_initialize_queue=false then expect test_files is nil to make fast request to API
|
253
|
-
).and_return(action)
|
254
|
-
|
255
|
-
connection = instance_double(KnapsackPro::Client::Connection,
|
256
|
-
call: response,
|
257
|
-
success?: success?,
|
258
|
-
errors?: errors?,
|
259
|
-
api_code: api_code)
|
260
|
-
expect(KnapsackPro::Client::Connection).to receive(:new).with(action).and_return(connection)
|
261
|
-
end
|
262
|
-
|
263
|
-
context 'when successful request to API' do
|
264
|
-
let(:success?) { true }
|
265
|
-
|
266
|
-
context 'when response has errors' do
|
267
|
-
let(:errors?) { true }
|
268
|
-
|
269
|
-
it do
|
270
|
-
expect { subject }.to raise_error(ArgumentError)
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
context 'when response has no errors' do
|
275
|
-
let(:errors?) { false }
|
276
|
-
|
277
|
-
context 'when response returns test files (successful attempt to connect to queue already existing on the API side)' do
|
278
|
-
let(:response) do
|
279
|
-
{
|
280
|
-
'test_files' => [
|
281
|
-
{ 'path' => 'a_spec.rb' },
|
282
|
-
{ 'path' => 'b_spec.rb' },
|
283
|
-
]
|
284
|
-
}
|
285
|
-
end
|
286
|
-
|
287
|
-
before do
|
288
|
-
expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(fast_and_slow_test_files_to_run, response['test_files']).and_call_original
|
289
|
-
end
|
290
|
-
|
291
|
-
it { should eq ['a_spec.rb', 'b_spec.rb'] }
|
292
|
-
end
|
293
|
-
end
|
294
|
-
end
|
295
|
-
|
296
|
-
context 'when not successful request to API' do
|
297
|
-
let(:success?) { false }
|
298
|
-
let(:errors?) { false }
|
299
|
-
|
300
|
-
it_behaves_like 'when connection to API failed (fallback mode)'
|
301
|
-
end
|
302
|
-
end
|
303
|
-
end
|
304
|
-
end
|