knapsack_pro 2.10.0 → 2.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -0
  3. data/README.md +31 -1562
  4. data/lib/knapsack_pro/adapters/base_adapter.rb +22 -0
  5. data/lib/knapsack_pro/adapters/rspec_adapter.rb +6 -2
  6. data/lib/knapsack_pro/allocator.rb +1 -1
  7. data/lib/knapsack_pro/base_allocator_builder.rb +0 -8
  8. data/lib/knapsack_pro/config/env.rb +1 -0
  9. data/lib/knapsack_pro/queue_allocator.rb +9 -20
  10. data/lib/knapsack_pro/queue_allocator_builder.rb +2 -2
  11. data/lib/knapsack_pro/report.rb +1 -1
  12. data/lib/knapsack_pro/runners/cucumber_runner.rb +4 -1
  13. data/lib/knapsack_pro/runners/minitest_runner.rb +4 -1
  14. data/lib/knapsack_pro/runners/queue/cucumber_runner.rb +4 -0
  15. data/lib/knapsack_pro/runners/queue/minitest_runner.rb +4 -0
  16. data/lib/knapsack_pro/runners/queue/rspec_runner.rb +2 -0
  17. data/lib/knapsack_pro/runners/rspec_runner.rb +4 -1
  18. data/lib/knapsack_pro/runners/spinach_runner.rb +4 -1
  19. data/lib/knapsack_pro/runners/test_unit_runner.rb +4 -1
  20. data/lib/knapsack_pro/slow_test_file_determiner.rb +1 -1
  21. data/lib/knapsack_pro/test_case_detectors/rspec_test_example_detector.rb +1 -1
  22. data/lib/knapsack_pro/tracker.rb +10 -6
  23. data/lib/knapsack_pro/version.rb +1 -1
  24. data/spec/knapsack_pro/adapters/base_adapter_spec.rb +51 -0
  25. data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +15 -9
  26. data/spec/knapsack_pro/queue_allocator_builder_spec.rb +6 -6
  27. data/spec/knapsack_pro/queue_allocator_spec.rb +33 -71
  28. data/spec/knapsack_pro/runners/cucumber_runner_spec.rb +2 -0
  29. data/spec/knapsack_pro/runners/minitest_runner_spec.rb +4 -0
  30. data/spec/knapsack_pro/runners/queue/cucumber_runner_spec.rb +27 -7
  31. data/spec/knapsack_pro/runners/queue/minitest_runner_spec.rb +27 -7
  32. data/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +2 -0
  33. data/spec/knapsack_pro/runners/rspec_runner_spec.rb +2 -0
  34. data/spec/knapsack_pro/runners/spinach_runner_spec.rb +2 -0
  35. data/spec/knapsack_pro/runners/test_unit_runner_spec.rb +2 -0
  36. data/spec/knapsack_pro/tracker_spec.rb +7 -3
  37. metadata +5 -5
@@ -8,11 +8,11 @@ describe KnapsackPro::QueueAllocatorBuilder do
8
8
  subject { allocator_builder.allocator }
9
9
 
10
10
  before do
11
- lazy_fast_and_slow_test_files_to_run = double
12
- expect(allocator_builder).to receive(:lazy_fast_and_slow_test_files_to_run).and_return(lazy_fast_and_slow_test_files_to_run)
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
13
 
14
- lazy_fallback_mode_test_files = double
15
- expect(allocator_builder).to receive(:lazy_fallback_mode_test_files).and_return(lazy_fallback_mode_test_files)
14
+ fallback_mode_test_files = double
15
+ expect(allocator_builder).to receive(:fallback_mode_test_files).and_return(fallback_mode_test_files)
16
16
 
17
17
  repository_adapter = double
18
18
  expect(KnapsackPro::RepositoryAdapterInitiator).to receive(:call).and_return(repository_adapter)
@@ -25,8 +25,8 @@ describe KnapsackPro::QueueAllocatorBuilder do
25
25
  expect(KnapsackPro::Config::Env).to receive(:ci_node_build_id).and_return(ci_node_build_id)
26
26
 
27
27
  expect(KnapsackPro::QueueAllocator).to receive(:new).with(
28
- lazy_fast_and_slow_test_files_to_run: lazy_fast_and_slow_test_files_to_run,
29
- lazy_fallback_mode_test_files: lazy_fallback_mode_test_files,
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
30
  ci_node_total: ci_node_total,
31
31
  ci_node_index: ci_node_index,
32
32
  ci_node_build_id: ci_node_build_id,
@@ -1,8 +1,6 @@
1
1
  describe KnapsackPro::QueueAllocator do
2
- let(:lazy_loaded_fast_and_slow_test_files_to_run) { double }
3
- let(:lazy_fast_and_slow_test_files_to_run) { double(call: lazy_loaded_fast_and_slow_test_files_to_run) }
4
- let(:lazy_loaded_fallback_mode_test_files) { double }
5
- let(:lazy_fallback_mode_test_files) { double(call: lazy_loaded_fallback_mode_test_files) }
2
+ let(:fast_and_slow_test_files_to_run) { double }
3
+ let(:fallback_mode_test_files) { double }
6
4
  let(:ci_node_total) { double }
7
5
  let(:ci_node_index) { double }
8
6
  let(:ci_node_build_id) { double }
@@ -10,8 +8,8 @@ describe KnapsackPro::QueueAllocator do
10
8
 
11
9
  let(:queue_allocator) do
12
10
  described_class.new(
13
- lazy_fast_and_slow_test_files_to_run: lazy_fast_and_slow_test_files_to_run,
14
- lazy_fallback_mode_test_files: lazy_fallback_mode_test_files,
11
+ fast_and_slow_test_files_to_run: fast_and_slow_test_files_to_run,
12
+ fallback_mode_test_files: fallback_mode_test_files,
15
13
  ci_node_total: ci_node_total,
16
14
  ci_node_index: ci_node_index,
17
15
  ci_node_build_id: ci_node_build_id,
@@ -66,7 +64,7 @@ describe KnapsackPro::QueueAllocator do
66
64
  context 'when fallback mode started' do
67
65
  before do
68
66
  test_flat_distributor = instance_double(KnapsackPro::TestFlatDistributor)
69
- expect(KnapsackPro::TestFlatDistributor).to receive(:new).with(lazy_loaded_fallback_mode_test_files, ci_node_total).and_return(test_flat_distributor)
67
+ expect(KnapsackPro::TestFlatDistributor).to receive(:new).with(fallback_mode_test_files, ci_node_total).and_return(test_flat_distributor)
70
68
  expect(test_flat_distributor).to receive(:test_files_for_node).with(ci_node_index).and_return([
71
69
  { 'path' => 'c_spec.rb' },
72
70
  { 'path' => 'd_spec.rb' },
@@ -133,32 +131,20 @@ describe KnapsackPro::QueueAllocator do
133
131
  let(:errors?) { false }
134
132
 
135
133
  context 'when response returns test files (successful attempt to connect to queue already existing on the API side)' do
136
- let(:test_files) do
137
- [
138
- { 'path' => 'a_spec.rb' },
139
- { 'path' => 'b_spec.rb' },
140
- ]
141
- end
142
134
  let(:response) do
143
- { 'test_files' => test_files }
135
+ {
136
+ 'test_files' => [
137
+ { 'path' => 'a_spec.rb' },
138
+ { 'path' => 'b_spec.rb' },
139
+ ]
140
+ }
144
141
  end
145
142
 
146
- context 'when test files encryption is enabled' do
147
- before do
148
- expect(KnapsackPro::Config::Env).to receive(:test_files_encrypted?).and_return(true)
149
- expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(lazy_loaded_fast_and_slow_test_files_to_run, response['test_files']).and_return(test_files)
150
- end
151
-
152
- it { should eq ['a_spec.rb', 'b_spec.rb'] }
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
153
145
  end
154
146
 
155
- context 'when test files encryption is disabled' do
156
- before do
157
- expect(KnapsackPro::Config::Env).to receive(:test_files_encrypted?).and_return(false)
158
- end
159
-
160
- it { should eq ['a_spec.rb', 'b_spec.rb'] }
161
- end
147
+ it { should eq ['a_spec.rb', 'b_spec.rb'] }
162
148
  end
163
149
 
164
150
  context 'when response has code=ATTEMPT_CONNECT_TO_QUEUE_FAILED' do
@@ -172,7 +158,7 @@ describe KnapsackPro::QueueAllocator do
172
158
  expect(KnapsackPro::Crypto::BranchEncryptor).to receive(:call).with(repository_adapter.branch).and_return(encrypted_branch)
173
159
 
174
160
  encrypted_test_files = double
175
- expect(KnapsackPro::Crypto::Encryptor).to receive(:call).with(lazy_loaded_fast_and_slow_test_files_to_run).and_return(encrypted_test_files)
161
+ expect(KnapsackPro::Crypto::Encryptor).to receive(:call).with(fast_and_slow_test_files_to_run).and_return(encrypted_test_files)
176
162
 
177
163
  # 2nd request is no more an attempt to connect to queue.
178
164
  # We want to try to initalize a new queue so we will also send list of test files from disk.
@@ -212,32 +198,20 @@ describe KnapsackPro::QueueAllocator do
212
198
  let(:response2_errors?) { false }
213
199
 
214
200
  context 'when 2nd response returns test files (successful attempt to connect to queue already existing on the API side)' do
215
- let(:test_files) do
216
- [
217
- { 'path' => 'a_spec.rb' },
218
- { 'path' => 'b_spec.rb' },
219
- ]
220
- end
221
201
  let(:response2) do
222
- { 'test_files' => test_files }
202
+ {
203
+ 'test_files' => [
204
+ { 'path' => 'a_spec.rb' },
205
+ { 'path' => 'b_spec.rb' },
206
+ ]
207
+ }
223
208
  end
224
209
 
225
- context 'when test files encryption is enabled' do
226
- before do
227
- expect(KnapsackPro::Config::Env).to receive(:test_files_encrypted?).and_return(true)
228
- expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(lazy_loaded_fast_and_slow_test_files_to_run, response2['test_files']).and_return(test_files)
229
- end
230
-
231
- it { should eq ['a_spec.rb', 'b_spec.rb'] }
210
+ before do
211
+ expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(fast_and_slow_test_files_to_run, response2['test_files']).and_call_original
232
212
  end
233
213
 
234
- context 'when test files encryption is disabled' do
235
- before do
236
- expect(KnapsackPro::Config::Env).to receive(:test_files_encrypted?).and_return(false)
237
- end
238
-
239
- it { should eq ['a_spec.rb', 'b_spec.rb'] }
240
- end
214
+ it { should eq ['a_spec.rb', 'b_spec.rb'] }
241
215
  end
242
216
  end
243
217
  end
@@ -304,32 +278,20 @@ describe KnapsackPro::QueueAllocator do
304
278
  let(:errors?) { false }
305
279
 
306
280
  context 'when response returns test files (successful attempt to connect to queue already existing on the API side)' do
307
- let(:test_files) do
308
- [
309
- { 'path' => 'a_spec.rb' },
310
- { 'path' => 'b_spec.rb' },
311
- ]
312
- end
313
281
  let(:response) do
314
- { 'test_files' => test_files }
282
+ {
283
+ 'test_files' => [
284
+ { 'path' => 'a_spec.rb' },
285
+ { 'path' => 'b_spec.rb' },
286
+ ]
287
+ }
315
288
  end
316
289
 
317
- context 'when test files encryption is enabled' do
318
- before do
319
- expect(KnapsackPro::Config::Env).to receive(:test_files_encrypted?).and_return(true)
320
- expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(lazy_loaded_fast_and_slow_test_files_to_run, response['test_files']).and_return(test_files)
321
- end
322
-
323
- it { should eq ['a_spec.rb', 'b_spec.rb'] }
290
+ before do
291
+ expect(KnapsackPro::Crypto::Decryptor).to receive(:call).with(fast_and_slow_test_files_to_run, response['test_files']).and_call_original
324
292
  end
325
293
 
326
- context 'when test files encryption is disabled' do
327
- before do
328
- expect(KnapsackPro::Config::Env).to receive(:test_files_encrypted?).and_return(false)
329
- end
330
-
331
- it { should eq ['a_spec.rb', 'b_spec.rb'] }
332
- end
294
+ it { should eq ['a_spec.rb', 'b_spec.rb'] }
333
295
  end
334
296
  end
335
297
  end
@@ -34,6 +34,8 @@ describe KnapsackPro::Runners::CucumberRunner do
34
34
  let(:task) { double }
35
35
 
36
36
  before do
37
+ expect(KnapsackPro::Adapters::CucumberAdapter).to receive(:verify_bind_method_called)
38
+
37
39
  expect(Rake::Task).to receive(:[]).with('knapsack_pro:cucumber_run').at_least(1).and_return(task)
38
40
 
39
41
  t = double
@@ -14,6 +14,10 @@ describe KnapsackPro::Runners::MinitestRunner do
14
14
  end
15
15
 
16
16
  context 'when test files were returned by Knapsack Pro API' do
17
+ before do
18
+ expect(KnapsackPro::Adapters::MinitestAdapter).to receive(:verify_bind_method_called)
19
+ end
20
+
17
21
  it 'runs tests' do
18
22
  test_file_paths = ['test_fake/a_test.rb', 'test_fake/b_test.rb']
19
23
  runner = instance_double(described_class,
@@ -167,14 +167,34 @@ describe KnapsackPro::Runners::Queue::CucumberRunner do
167
167
  context "when test files don't exist" do
168
168
  let(:test_file_paths) { [] }
169
169
 
170
- it 'returns exit code 0' do
171
- expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
172
- expect(KnapsackPro::Report).to receive(:save_node_queue_to_api)
170
+ context 'when all_test_file_paths exist' do
171
+ let(:all_test_file_paths) { ['features/a.feature'] }
173
172
 
174
- expect(subject).to eq({
175
- status: :completed,
176
- exitstatus: exitstatus,
177
- })
173
+ it 'returns exit code 0' do
174
+ expect(KnapsackPro::Adapters::CucumberAdapter).to receive(:verify_bind_method_called)
175
+
176
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
177
+ expect(KnapsackPro::Report).to receive(:save_node_queue_to_api)
178
+
179
+ expect(subject).to eq({
180
+ status: :completed,
181
+ exitstatus: exitstatus,
182
+ })
183
+ end
184
+ end
185
+
186
+ context "when all_test_file_paths don't exist" do
187
+ let(:all_test_file_paths) { [] }
188
+
189
+ it 'returns exit code 0' do
190
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
191
+ expect(KnapsackPro::Report).to receive(:save_node_queue_to_api)
192
+
193
+ expect(subject).to eq({
194
+ status: :completed,
195
+ exitstatus: exitstatus,
196
+ })
197
+ end
178
198
  end
179
199
  end
180
200
  end
@@ -159,14 +159,34 @@ describe KnapsackPro::Runners::Queue::MinitestRunner do
159
159
  context "when test files don't exist" do
160
160
  let(:test_file_paths) { [] }
161
161
 
162
- it 'returns exit code 0' do
163
- expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
164
- expect(KnapsackPro::Report).to receive(:save_node_queue_to_api)
162
+ context 'when all_test_file_paths exist' do
163
+ let(:all_test_file_paths) { ['a_test.rb'] }
165
164
 
166
- expect(subject).to eq({
167
- status: :completed,
168
- exitstatus: exitstatus,
169
- })
165
+ it 'returns exit code 0' do
166
+ expect(KnapsackPro::Adapters::MinitestAdapter).to receive(:verify_bind_method_called)
167
+
168
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
169
+ expect(KnapsackPro::Report).to receive(:save_node_queue_to_api)
170
+
171
+ expect(subject).to eq({
172
+ status: :completed,
173
+ exitstatus: exitstatus,
174
+ })
175
+ end
176
+ end
177
+
178
+ context "when all_test_file_paths don't exist" do
179
+ let(:all_test_file_paths) { [] }
180
+
181
+ it 'returns exit code 0' do
182
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
183
+ expect(KnapsackPro::Report).to receive(:save_node_queue_to_api)
184
+
185
+ expect(subject).to eq({
186
+ status: :completed,
187
+ exitstatus: exitstatus,
188
+ })
189
+ end
170
190
  end
171
191
  end
172
192
  end
@@ -249,6 +249,8 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
249
249
  let(:all_test_file_paths) { ['a_spec.rb'] }
250
250
 
251
251
  it do
252
+ expect(KnapsackPro::Adapters::RSpecAdapter).to receive(:verify_bind_method_called)
253
+
252
254
  expect(KnapsackPro::Formatters::RSpecQueueSummaryFormatter).to receive(:print_summary)
253
255
  expect(KnapsackPro::Formatters::RSpecQueueProfileFormatterExtension).to receive(:print_summary)
254
256
 
@@ -34,6 +34,8 @@ describe KnapsackPro::Runners::RSpecRunner do
34
34
  let(:task) { double }
35
35
 
36
36
  before do
37
+ expect(KnapsackPro::Adapters::RSpecAdapter).to receive(:verify_bind_method_called)
38
+
37
39
  expect(Rake::Task).to receive(:[]).with('knapsack_pro:rspec_run').at_least(1).and_return(task)
38
40
 
39
41
  t = double
@@ -26,6 +26,8 @@ describe KnapsackPro::Runners::SpinachRunner do
26
26
  end
27
27
 
28
28
  before do
29
+ expect(KnapsackPro::Adapters::SpinachAdapter).to receive(:verify_bind_method_called)
30
+
29
31
  expect(Kernel).to receive(:system).with('KNAPSACK_PRO_RECORDING_ENABLED=true KNAPSACK_PRO_TEST_SUITE_TOKEN=spinach-token bundle exec spinach --custom-arg --features_path fake-test-dir -- features/a.feature features/b.feature')
30
32
  end
31
33
 
@@ -16,6 +16,8 @@ describe KnapsackPro::Runners::TestUnitRunner do
16
16
 
17
17
  context 'when test files were returned by Knapsack Pro API' do
18
18
  it 'runs tests' do
19
+ expect(KnapsackPro::Adapters::TestUnitAdapter).to receive(:verify_bind_method_called)
20
+
19
21
  test_file_paths = ['test-unit_fake/a_test.rb', 'test-unit_fake/b_test.rb']
20
22
  runner = instance_double(described_class,
21
23
  test_dir: 'test-unit_fake',
@@ -12,9 +12,7 @@ describe KnapsackPro::Tracker do
12
12
  subject { tracker.current_test_path }
13
13
 
14
14
  context 'when current_test_path not set' do
15
- it do
16
- expect { subject }.to raise_error("current_test_path needs to be set by Knapsack Pro Adapter's bind method")
17
- end
15
+ it { expect(subject).to be_nil }
18
16
  end
19
17
 
20
18
  context 'when current_test_path set' do
@@ -58,6 +56,9 @@ describe KnapsackPro::Tracker do
58
56
  it { expect(tracker.test_files_with_time.keys.size).to eql 2 }
59
57
  it { expect(tracker.test_files_with_time['a_spec.rb'][:time_execution]).to be_within(delta).of(0.1) }
60
58
  it { expect(tracker.test_files_with_time['b_spec.rb'][:time_execution]).to be_within(delta).of(0.2) }
59
+ it 'resets current_test_path after time is measured' do
60
+ expect(tracker.current_test_path).to be_nil
61
+ end
61
62
  it_behaves_like '#to_a'
62
63
  end
63
64
 
@@ -83,6 +84,9 @@ describe KnapsackPro::Tracker do
83
84
  it { expect(tracker.test_files_with_time.keys.size).to eql 2 }
84
85
  it { expect(tracker.test_files_with_time['a_spec.rb'][:time_execution]).to be_within(delta).of(0) }
85
86
  it { expect(tracker.test_files_with_time['b_spec.rb'][:time_execution]).to be_within(delta).of(0) }
87
+ it 'resets current_test_path after time is measured' do
88
+ expect(tracker.current_test_path).to be_nil
89
+ end
86
90
  it_behaves_like '#to_a'
87
91
  end
88
92
 
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.10.0
4
+ version: 2.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ArturT
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-25 00:00:00.000000000 Z
11
+ date: 2021-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -408,7 +408,7 @@ metadata:
408
408
  documentation_uri: https://docs.knapsackpro.com/integration/
409
409
  homepage_uri: https://knapsackpro.com
410
410
  source_code_uri: https://github.com/KnapsackPro/knapsack_pro-ruby
411
- post_install_message:
411
+ post_install_message:
412
412
  rdoc_options: []
413
413
  require_paths:
414
414
  - lib
@@ -424,7 +424,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
424
424
  version: '0'
425
425
  requirements: []
426
426
  rubygems_version: 3.0.6
427
- signing_key:
427
+ signing_key:
428
428
  specification_version: 4
429
429
  summary: Knapsack Pro splits tests across parallel CI nodes and ensures each parallel
430
430
  job finish work at a similar time.