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.
@@ -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