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.
@@ -99,106 +99,4 @@ describe KnapsackPro::BaseAllocatorBuilder do
99
99
  end
100
100
  end
101
101
  end
102
-
103
- describe '#fallback_mode_test_files' do
104
- subject { allocator_builder.fallback_mode_test_files }
105
-
106
- it do
107
- test_file_pattern = double
108
- expect(KnapsackPro::TestFilePattern).to receive(:call).with(adapter_class).and_return(test_file_pattern)
109
-
110
- test_files = double
111
- expect(KnapsackPro::TestFileFinder).to receive(:call).with(test_file_pattern).and_return(test_files)
112
-
113
- expect(subject).to eq test_files
114
- end
115
- end
116
-
117
- describe '#fast_and_slow_test_files_to_run' do
118
- subject { allocator_builder.fast_and_slow_test_files_to_run }
119
-
120
- context 'when split by test cases disabled' do
121
- it 'returns test files to run based on test files on the disk' do
122
- test_file_pattern = double
123
- expect(KnapsackPro::TestFilePattern).to receive(:call).with(adapter_class).and_return(test_file_pattern)
124
-
125
- test_files = double
126
- expect(KnapsackPro::TestFileFinder).to receive(:call).with(test_file_pattern).and_return(test_files)
127
-
128
- expect(subject).to eq test_files
129
- end
130
- end
131
-
132
- context 'when split by test cases enabled' do
133
- let(:test_files_to_run) { double }
134
-
135
- before do
136
- expect(adapter_class).to receive(:split_by_test_cases_enabled?).and_return(true)
137
-
138
- test_file_pattern = double
139
- expect(KnapsackPro::TestFilePattern).to receive(:call).with(adapter_class).and_return(test_file_pattern)
140
-
141
- expect(KnapsackPro::TestFileFinder).to receive(:call).with(test_file_pattern).and_return(test_files_to_run)
142
-
143
- expect(allocator_builder).to receive(:get_slow_test_files).and_return(slow_test_files)
144
- end
145
-
146
- context 'when slow test files are detected' do
147
- let(:slow_test_files) do
148
- [
149
- '1_spec.rb',
150
- '2_spec.rb',
151
- ]
152
- end
153
-
154
- it 'returns test files with test cases' do
155
- test_file_cases = double
156
- expect(adapter_class).to receive(:test_file_cases_for).with(slow_test_files).and_return(test_file_cases)
157
-
158
- test_files_with_test_cases = double
159
- expect(KnapsackPro::TestFilesWithTestCasesComposer).to receive(:call).with(test_files_to_run, slow_test_files, test_file_cases).and_return(test_files_with_test_cases)
160
-
161
- expect(subject).to eq test_files_with_test_cases
162
- end
163
- end
164
-
165
- context 'when slow test files are not detected' do
166
- let(:slow_test_files) { [] }
167
-
168
- it 'returns test files without test cases' do
169
- expect(subject).to eq test_files_to_run
170
- end
171
- end
172
- end
173
- end
174
-
175
- describe 'private #get_slow_test_files' do
176
- subject { allocator_builder.send(:get_slow_test_files) }
177
-
178
- before do
179
- expect(KnapsackPro::Config::Env).to receive(:slow_test_file_pattern).and_return(slow_test_file_pattern)
180
- end
181
-
182
- context 'when slow test file pattern is present' do
183
- let(:slow_test_files) { double(:slow_test_files_based_on_pattern, size: 3) }
184
- let(:slow_test_file_pattern) { double }
185
-
186
- before do
187
- expect(KnapsackPro::TestFileFinder).to receive(:slow_test_files_by_pattern).with(adapter_class).and_return(slow_test_files)
188
- end
189
-
190
- it { expect(subject).to eq slow_test_files }
191
- end
192
-
193
- context 'when slow test file pattern is not present' do
194
- let(:slow_test_files) { double(:slow_test_files_based_on_api, size: 2) }
195
- let(:slow_test_file_pattern) { nil }
196
-
197
- before do
198
- expect(KnapsackPro::SlowTestFileFinder).to receive(:call).with(adapter_class).and_return(slow_test_files)
199
- end
200
-
201
- it { expect(subject).to eq slow_test_files }
202
- end
203
- end
204
102
  end
@@ -15,7 +15,9 @@ describe KnapsackPro::Crypto::Decryptor do
15
15
  let(:decryptor) { described_class.new(test_files, encrypted_test_files) }
16
16
 
17
17
  describe '.call' do
18
- subject { described_class.call(test_files, encrypted_test_files) }
18
+ let(:test_suite) { instance_double(KnapsackPro::TestSuite, calculate_test_files: instance_double(KnapsackPro::TestSuite::Result, test_files: test_files)) }
19
+
20
+ subject { described_class.call(test_suite, encrypted_test_files) }
19
21
 
20
22
  before do
21
23
  expect(KnapsackPro::Config::Env).to receive(:test_files_encrypted?).and_return(test_files_encrypted?)
@@ -12,11 +12,11 @@ describe KnapsackPro::Runners::BaseRunner do
12
12
  let(:runner) do
13
13
  described_class.new(adapter_class)
14
14
  end
15
- let(:allocator) { instance_double(KnapsackPro::Allocator) }
16
- let(:allocator_builder) { instance_double(KnapsackPro::AllocatorBuilder) }
15
+ let(:allocator) { instance_double(KnapsackPro::RegularAllocator) }
16
+ let(:allocator_builder) { instance_double(KnapsackPro::RegularAllocatorBuilder) }
17
17
 
18
18
  before do
19
- expect(KnapsackPro::AllocatorBuilder).to receive(:new).with(adapter_class).and_return(allocator_builder)
19
+ expect(KnapsackPro::RegularAllocatorBuilder).to receive(:new).with(adapter_class).and_return(allocator_builder)
20
20
  expect(allocator_builder).to receive(:allocator).and_return(allocator)
21
21
  end
22
22
 
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.0.2
4
+ version: 8.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ArturT
@@ -224,8 +224,6 @@ files:
224
224
  - lib/knapsack_pro/adapters/rspec_adapter.rb
225
225
  - lib/knapsack_pro/adapters/spinach_adapter.rb
226
226
  - lib/knapsack_pro/adapters/test_unit_adapter.rb
227
- - lib/knapsack_pro/allocator.rb
228
- - lib/knapsack_pro/allocator_builder.rb
229
227
  - lib/knapsack_pro/base_allocator_builder.rb
230
228
  - lib/knapsack_pro/batch.rb
231
229
  - lib/knapsack_pro/build_distribution_fetcher.rb
@@ -268,6 +266,8 @@ files:
268
266
  - lib/knapsack_pro/queue_allocator.rb
269
267
  - lib/knapsack_pro/queue_allocator_builder.rb
270
268
  - lib/knapsack_pro/railtie.rb
269
+ - lib/knapsack_pro/regular_allocator.rb
270
+ - lib/knapsack_pro/regular_allocator_builder.rb
271
271
  - lib/knapsack_pro/report.rb
272
272
  - lib/knapsack_pro/repository_adapter_initiator.rb
273
273
  - lib/knapsack_pro/repository_adapters/base_adapter.rb
@@ -295,6 +295,7 @@ files:
295
295
  - lib/knapsack_pro/test_file_presenter.rb
296
296
  - lib/knapsack_pro/test_files_with_test_cases_composer.rb
297
297
  - lib/knapsack_pro/test_flat_distributor.rb
298
+ - lib/knapsack_pro/test_suite.rb
298
299
  - lib/knapsack_pro/tracker.rb
299
300
  - lib/knapsack_pro/urls.rb
300
301
  - lib/knapsack_pro/utils.rb
@@ -329,8 +330,6 @@ files:
329
330
  - spec/knapsack_pro/adapters/rspec_adapter_spec.rb
330
331
  - spec/knapsack_pro/adapters/spinach_adapter_spec.rb
331
332
  - spec/knapsack_pro/adapters/test_unit_adapter_spec.rb
332
- - spec/knapsack_pro/allocator_builder_spec.rb
333
- - spec/knapsack_pro/allocator_spec.rb
334
333
  - spec/knapsack_pro/base_allocator_builder_spec.rb
335
334
  - spec/knapsack_pro/build_distribution_fetcher_spec.rb
336
335
  - spec/knapsack_pro/client/api/action_spec.rb
@@ -365,8 +364,6 @@ files:
365
364
  - spec/knapsack_pro/logger_wrapper_spec.rb
366
365
  - spec/knapsack_pro/presenter_spec.rb
367
366
  - spec/knapsack_pro/pure/queue/rspec_pure_spec.rb
368
- - spec/knapsack_pro/queue_allocator_builder_spec.rb
369
- - spec/knapsack_pro/queue_allocator_spec.rb
370
367
  - spec/knapsack_pro/queue_spec.rb
371
368
  - spec/knapsack_pro/report_spec.rb
372
369
  - spec/knapsack_pro/repository_adapter_initiator_spec.rb
@@ -455,8 +452,6 @@ test_files:
455
452
  - spec/knapsack_pro/adapters/rspec_adapter_spec.rb
456
453
  - spec/knapsack_pro/adapters/spinach_adapter_spec.rb
457
454
  - spec/knapsack_pro/adapters/test_unit_adapter_spec.rb
458
- - spec/knapsack_pro/allocator_builder_spec.rb
459
- - spec/knapsack_pro/allocator_spec.rb
460
455
  - spec/knapsack_pro/base_allocator_builder_spec.rb
461
456
  - spec/knapsack_pro/build_distribution_fetcher_spec.rb
462
457
  - spec/knapsack_pro/client/api/action_spec.rb
@@ -491,8 +486,6 @@ test_files:
491
486
  - spec/knapsack_pro/logger_wrapper_spec.rb
492
487
  - spec/knapsack_pro/presenter_spec.rb
493
488
  - spec/knapsack_pro/pure/queue/rspec_pure_spec.rb
494
- - spec/knapsack_pro/queue_allocator_builder_spec.rb
495
- - spec/knapsack_pro/queue_allocator_spec.rb
496
489
  - spec/knapsack_pro/queue_spec.rb
497
490
  - spec/knapsack_pro/report_spec.rb
498
491
  - spec/knapsack_pro/repository_adapter_initiator_spec.rb
@@ -1,36 +0,0 @@
1
- describe KnapsackPro::AllocatorBuilder do
2
- let(:adapter_class) { KnapsackPro::Adapters::BaseAdapter }
3
- let(:allocator_builder) { described_class.new(adapter_class) }
4
-
5
- describe '#allocator' do
6
- let(:allocator) { double }
7
-
8
- subject { allocator_builder.allocator }
9
-
10
- before do
11
- fast_and_slow_test_files_to_run = double
12
- expect(allocator_builder).to receive(:fast_and_slow_test_files_to_run).and_return(fast_and_slow_test_files_to_run)
13
-
14
- fallback_mode_test_files = double
15
- expect(allocator_builder).to receive(:fallback_mode_test_files).and_return(fallback_mode_test_files)
16
-
17
- repository_adapter = double
18
- expect(KnapsackPro::RepositoryAdapterInitiator).to receive(:call).and_return(repository_adapter)
19
-
20
- ci_node_total = double
21
- expect(KnapsackPro::Config::Env).to receive(:ci_node_total).and_return(ci_node_total)
22
- ci_node_index = double
23
- expect(KnapsackPro::Config::Env).to receive(:ci_node_index).and_return(ci_node_index)
24
-
25
- expect(KnapsackPro::Allocator).to receive(:new).with(
26
- fast_and_slow_test_files_to_run: fast_and_slow_test_files_to_run,
27
- fallback_mode_test_files: fallback_mode_test_files,
28
- ci_node_total: ci_node_total,
29
- ci_node_index: ci_node_index,
30
- repository_adapter: repository_adapter,
31
- ).and_return(allocator)
32
- end
33
-
34
- it { should eq allocator }
35
- end
36
- end
@@ -1,233 +0,0 @@
1
- describe KnapsackPro::Allocator 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(:repository_adapter) { instance_double(KnapsackPro::RepositoryAdapters::EnvAdapter, commit_hash: double, branch: double) }
7
-
8
- let(:allocator) do
9
- described_class.new(
10
- fast_and_slow_test_files_to_run: fast_and_slow_test_files_to_run,
11
- fallback_mode_test_files: fallback_mode_test_files,
12
- ci_node_total: ci_node_total,
13
- ci_node_index: ci_node_index,
14
- repository_adapter: repository_adapter
15
- )
16
- end
17
-
18
- describe '#test_file_paths' do
19
- let(:response) { double }
20
- let(:api_code) { nil }
21
-
22
- subject { allocator.test_file_paths }
23
-
24
- shared_examples_for 'when connection to API failed (fallback mode)' do
25
- context 'when fallback mode is disabled' do
26
- before(:each) do
27
- expect(KnapsackPro::Config::Env).to receive(:fallback_mode_enabled?).and_return(false)
28
- end
29
-
30
- it 'logs the error and exits' do
31
- logger = instance_double(Logger)
32
- allow(KnapsackPro).to receive(:logger).and_return(logger)
33
- expect(logger).to receive(:error).with(
34
- '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'
35
- )
36
-
37
- expect { subject }.to raise_error(SystemExit)
38
- end
39
- end
40
-
41
- context 'when CI node retry count > 0' do
42
- before(:each) do
43
- expect(KnapsackPro::Config::Env).to receive(:ci_node_retry_count).and_return(1)
44
- end
45
-
46
- context 'when fixed_test_suite_split=true' do
47
- before(:each) do
48
- expect(KnapsackPro::Config::Env).to receive(:fixed_test_suite_split).and_return(true)
49
- end
50
-
51
- it 'logs the error and exits' do
52
- logger = instance_double(Logger)
53
- allow(KnapsackPro).to receive(:logger).and_return(logger)
54
-
55
- expect(logger).to receive(:error).with(
56
- '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'
57
- )
58
-
59
- expect { subject }.to raise_error(SystemExit)
60
- end
61
- end
62
-
63
- context 'when fixed_test_suite_split=false' do
64
- before(:each) do
65
- expect(KnapsackPro::Config::Env).to receive(:fixed_test_suite_split).and_return(false)
66
- end
67
-
68
- it 'logs the error and exits' do
69
- logger = instance_double(Logger)
70
- allow(KnapsackPro).to receive(:logger).and_return(logger)
71
-
72
- expect(logger).to receive(:error).with(
73
- '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 Please ensure you have set KNAPSACK_PRO_FIXED_TEST_SUITE_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-test-suite-split'
74
- )
75
-
76
- expect { subject }.to raise_error(SystemExit)
77
- end
78
- end
79
- end
80
-
81
- context 'when fallback mode started' do
82
- before(:each) do
83
- test_flat_distributor = instance_double(KnapsackPro::TestFlatDistributor)
84
- expect(KnapsackPro::TestFlatDistributor).to receive(:new).with(fallback_mode_test_files, ci_node_total).and_return(test_flat_distributor)
85
- expect(test_flat_distributor).to receive(:test_files_for_node).with(ci_node_index).and_return([
86
- { 'path' => 'c_spec.rb' },
87
- { 'path' => 'd_spec.rb' },
88
- ])
89
- end
90
-
91
- it { should eq ['c_spec.rb', 'd_spec.rb'] }
92
- end
93
- end
94
-
95
- before(:each) 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::BuildDistributions).to receive(:subset).with({
101
- cache_read_attempt: true,
102
- commit_hash: repository_adapter.commit_hash,
103
- branch: encrypted_branch,
104
- node_total: ci_node_total,
105
- node_index: ci_node_index,
106
- test_files: nil, # when `cache_read_attempt=true`, then expect `test_files` is `nil` to make the request fast due to a small payload
107
- }).and_return(action)
108
-
109
- connection = instance_double(KnapsackPro::Client::Connection,
110
- call: response,
111
- success?: success?,
112
- errors?: errors?,
113
- api_code: api_code)
114
- expect(KnapsackPro::Client::Connection).to receive(:new).with(action).and_return(connection)
115
- end
116
-
117
- context 'when successful request to API' do
118
- let(:success?) { true }
119
-
120
- context 'when response has errors' do
121
- let(:errors?) { true }
122
-
123
- it do
124
- expect { subject }.to raise_error(ArgumentError)
125
- end
126
- end
127
-
128
- context 'when response has no errors' do
129
- let(:errors?) { false }
130
-
131
- context 'when the response returns test files (successful attempt to read from the cache - the cached test suite split exists on the API side)' do
132
- let(:response) do
133
- {
134
- 'test_files' => [
135
- { 'path' => 'a_spec.rb' },
136
- { 'path' => 'b_spec.rb' },
137
- ]
138
- }
139
- end
140
-
141
- before(:each) do
142
- expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(fast_and_slow_test_files_to_run, response['test_files']).and_call_original
143
- end
144
-
145
- it { should eq ['a_spec.rb', 'b_spec.rb'] }
146
- end
147
-
148
- context 'when the response has the API code=TEST_SUITE_SPLIT_CACHE_MISS' do
149
- let(:response) do
150
- { 'code' => 'TEST_SUITE_SPLIT_CACHE_MISS' }
151
- end
152
- let(:api_code) { 'TEST_SUITE_SPLIT_CACHE_MISS' }
153
-
154
- before(:each) do
155
- encrypted_branch = double
156
- expect(KnapsackPro::Crypto::BranchEncryptor).to receive(:call).with(repository_adapter.branch).and_return(encrypted_branch)
157
-
158
- encrypted_test_files = double
159
- expect(KnapsackPro::Crypto::Encryptor).to receive(:call).with(fast_and_slow_test_files_to_run).and_return(encrypted_test_files)
160
-
161
- # 2nd request is not an attempt to read from the cache.
162
- # Try to initalize a new test suite split by sending a list of test files from the disk.
163
- action = double
164
- expect(KnapsackPro::Client::API::V1::BuildDistributions).to receive(:subset).with({
165
- cache_read_attempt: 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
- test_files: encrypted_test_files,
171
- }).and_return(action)
172
-
173
- connection = instance_double(KnapsackPro::Client::Connection,
174
- call: response2,
175
- success?: response2_success?,
176
- errors?: response2_errors?,
177
- api_code: nil)
178
- expect(KnapsackPro::Client::Connection).to receive(:new).with(action).and_return(connection)
179
- end
180
-
181
- context 'when successful 2nd request to API' do
182
- let(:response2_success?) { true }
183
-
184
- context 'when 2nd response has errors' do
185
- let(:response2_errors?) { true }
186
- let(:response2) { nil }
187
-
188
- it do
189
- expect { subject }.to raise_error(ArgumentError)
190
- end
191
- end
192
-
193
- context 'when 2nd response has no errors' do
194
- let(:response2_errors?) { false }
195
-
196
- context 'when 2nd response returns test files' do
197
- let(:response2) do
198
- {
199
- 'test_files' => [
200
- { 'path' => 'a_spec.rb' },
201
- { 'path' => 'b_spec.rb' },
202
- ]
203
- }
204
- end
205
-
206
- before(:each) do
207
- expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(fast_and_slow_test_files_to_run, response2['test_files']).and_call_original
208
- end
209
-
210
- it { should eq ['a_spec.rb', 'b_spec.rb'] }
211
- end
212
- end
213
- end
214
-
215
- context 'when not successful 2nd request to API' do
216
- let(:response2_success?) { false }
217
- let(:response2_errors?) { false }
218
- let(:response2) { nil }
219
-
220
- it_behaves_like 'when connection to API failed (fallback mode)'
221
- end
222
- end
223
- end
224
- end
225
-
226
- context 'when not successful request to API' do
227
- let(:success?) { false }
228
- let(:errors?) { false }
229
-
230
- it_behaves_like 'when connection to API failed (fallback mode)'
231
- end
232
- end
233
- end
@@ -1,39 +0,0 @@
1
- describe KnapsackPro::QueueAllocatorBuilder do
2
- let(:adapter_class) { KnapsackPro::Adapters::BaseAdapter }
3
- let(:allocator_builder) { described_class.new(adapter_class) }
4
-
5
- describe '#allocator' do
6
- let(:allocator) { double }
7
-
8
- subject { allocator_builder.allocator }
9
-
10
- before do
11
- fast_and_slow_test_files_to_run = double
12
- expect(allocator_builder).to receive(:fast_and_slow_test_files_to_run).and_return(fast_and_slow_test_files_to_run)
13
-
14
- fallback_mode_test_files = double
15
- expect(allocator_builder).to receive(:fallback_mode_test_files).and_return(fallback_mode_test_files)
16
-
17
- repository_adapter = double
18
- expect(KnapsackPro::RepositoryAdapterInitiator).to receive(:call).and_return(repository_adapter)
19
-
20
- ci_node_total = double
21
- expect(KnapsackPro::Config::Env).to receive(:ci_node_total).and_return(ci_node_total)
22
- ci_node_index = double
23
- expect(KnapsackPro::Config::Env).to receive(:ci_node_index).and_return(ci_node_index)
24
- ci_node_build_id = double
25
- expect(KnapsackPro::Config::Env).to receive(:ci_node_build_id).and_return(ci_node_build_id)
26
-
27
- expect(KnapsackPro::QueueAllocator).to receive(:new).with(
28
- fast_and_slow_test_files_to_run: fast_and_slow_test_files_to_run,
29
- fallback_mode_test_files: fallback_mode_test_files,
30
- ci_node_total: ci_node_total,
31
- ci_node_index: ci_node_index,
32
- ci_node_build_id: ci_node_build_id,
33
- repository_adapter: repository_adapter,
34
- ).and_return(allocator)
35
- end
36
-
37
- it { should eq allocator }
38
- end
39
- end