knapsack_pro 6.0.4 → 7.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +80 -19
  3. data/.github/pull_request_template.md +22 -0
  4. data/.gitignore +4 -0
  5. data/CHANGELOG.md +87 -0
  6. data/Gemfile +9 -0
  7. data/README.md +0 -4
  8. data/knapsack_pro.gemspec +2 -1
  9. data/lib/knapsack_pro/adapters/base_adapter.rb +7 -2
  10. data/lib/knapsack_pro/adapters/cucumber_adapter.rb +1 -3
  11. data/lib/knapsack_pro/adapters/rspec_adapter.rb +16 -9
  12. data/lib/knapsack_pro/config/env.rb +1 -9
  13. data/lib/knapsack_pro/extensions/rspec_extension.rb +137 -0
  14. data/lib/knapsack_pro/formatters/time_tracker.rb +10 -26
  15. data/lib/knapsack_pro/formatters/time_tracker_fetcher.rb +6 -0
  16. data/lib/knapsack_pro/presenter.rb +1 -1
  17. data/lib/knapsack_pro/pure/queue/rspec_pure.rb +92 -0
  18. data/lib/knapsack_pro/runners/queue/base_runner.rb +6 -1
  19. data/lib/knapsack_pro/runners/queue/cucumber_runner.rb +6 -6
  20. data/lib/knapsack_pro/runners/queue/minitest_runner.rb +6 -6
  21. data/lib/knapsack_pro/runners/queue/rspec_runner.rb +124 -173
  22. data/lib/knapsack_pro/urls.rb +2 -0
  23. data/lib/knapsack_pro/version.rb +1 -1
  24. data/lib/knapsack_pro.rb +1 -0
  25. data/spec/integration/runners/queue/rspec_runner.rb +80 -0
  26. data/spec/integration/runners/queue/rspec_runner_spec.rb +2232 -0
  27. data/spec/knapsack_pro/adapters/base_adapter_spec.rb +17 -11
  28. data/spec/knapsack_pro/adapters/cucumber_adapter_spec.rb +2 -5
  29. data/spec/knapsack_pro/adapters/rspec_adapter_spec.rb +2 -24
  30. data/spec/knapsack_pro/config/env_spec.rb +1 -35
  31. data/spec/knapsack_pro/formatters/time_tracker_specs.rb +8 -37
  32. data/spec/knapsack_pro/hooks/queue_spec.rb +2 -2
  33. data/spec/knapsack_pro/presenter_spec.rb +1 -1
  34. data/spec/knapsack_pro/pure/queue/rspec_pure_spec.rb +224 -0
  35. data/spec/knapsack_pro/runners/queue/cucumber_runner_spec.rb +16 -16
  36. data/spec/knapsack_pro/runners/queue/minitest_runner_spec.rb +14 -14
  37. data/spec/knapsack_pro_spec.rb +3 -3
  38. metadata +17 -12
  39. data/lib/knapsack_pro/formatters/rspec_queue_profile_formatter_extension.rb +0 -58
  40. data/lib/knapsack_pro/formatters/rspec_queue_summary_formatter.rb +0 -145
  41. data/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +0 -536
@@ -26,7 +26,7 @@ describe KnapsackPro::Runners::Queue::MinitestRunner do
26
26
  expect($LOAD_PATH).to receive(:unshift).with(test_dir)
27
27
  end
28
28
 
29
- context 'when args provided' do
29
+ context 'when args are provided' do
30
30
  let(:args) { '--verbose --pride' }
31
31
 
32
32
  it do
@@ -41,7 +41,7 @@ describe KnapsackPro::Runners::Queue::MinitestRunner do
41
41
  can_initialize_queue: true,
42
42
  args: ['--verbose', '--pride'],
43
43
  exitstatus: 0,
44
- all_test_file_paths: [],
44
+ node_test_file_paths: [],
45
45
  }
46
46
  expect(described_class).to receive(:handle_signal!)
47
47
  expect(described_class).to receive(:run_tests).with(accumulator).and_return(expected_accumulator)
@@ -52,7 +52,7 @@ describe KnapsackPro::Runners::Queue::MinitestRunner do
52
52
  end
53
53
  end
54
54
 
55
- context 'when args not provided' do
55
+ context 'when args are not provided' do
56
56
  let(:args) { nil }
57
57
 
58
58
  it do
@@ -67,7 +67,7 @@ describe KnapsackPro::Runners::Queue::MinitestRunner do
67
67
  can_initialize_queue: true,
68
68
  args: [],
69
69
  exitstatus: 0,
70
- all_test_file_paths: [],
70
+ node_test_file_paths: [],
71
71
  }
72
72
  expect(described_class).to receive(:handle_signal!)
73
73
  expect(described_class).to receive(:run_tests).with(accumulator).and_return(expected_accumulator)
@@ -84,21 +84,21 @@ describe KnapsackPro::Runners::Queue::MinitestRunner do
84
84
  let(:can_initialize_queue) { double(:can_initialize_queue) }
85
85
  let(:args) { ['--verbose', '--pride'] }
86
86
  let(:exitstatus) { 0 }
87
- let(:all_test_file_paths) { [] }
87
+ let(:node_test_file_paths) { [] }
88
88
  let(:accumulator) do
89
89
  {
90
90
  runner: runner,
91
91
  can_initialize_queue: can_initialize_queue,
92
92
  args: args,
93
93
  exitstatus: exitstatus,
94
- all_test_file_paths: all_test_file_paths,
94
+ node_test_file_paths: node_test_file_paths,
95
95
  }
96
96
  end
97
97
 
98
98
  subject { described_class.run_tests(accumulator) }
99
99
 
100
100
  before do
101
- expect(runner).to receive(:test_file_paths).with(can_initialize_queue: can_initialize_queue, executed_test_files: all_test_file_paths).and_return(test_file_paths)
101
+ expect(runner).to receive(:test_file_paths).with(can_initialize_queue: can_initialize_queue, executed_test_files: node_test_file_paths).and_return(test_file_paths)
102
102
  end
103
103
 
104
104
  context 'when test files exist' do
@@ -145,7 +145,7 @@ describe KnapsackPro::Runners::Queue::MinitestRunner do
145
145
  can_initialize_queue: false,
146
146
  args: args,
147
147
  exitstatus: exitstatus,
148
- all_test_file_paths: test_file_paths,
148
+ node_test_file_paths: test_file_paths,
149
149
  })
150
150
  end
151
151
  end
@@ -160,17 +160,17 @@ describe KnapsackPro::Runners::Queue::MinitestRunner do
160
160
  can_initialize_queue: false,
161
161
  args: args,
162
162
  exitstatus: 1, # tests failed
163
- all_test_file_paths: test_file_paths,
163
+ node_test_file_paths: test_file_paths,
164
164
  })
165
165
  end
166
166
  end
167
167
  end
168
168
 
169
- context "when test files don't exist" do
169
+ context 'when test files do not exist' do
170
170
  let(:test_file_paths) { [] }
171
171
 
172
- context 'when all_test_file_paths exist' do
173
- let(:all_test_file_paths) { ['a_test.rb'] }
172
+ context 'when node_test_file_paths exists' do
173
+ let(:node_test_file_paths) { ['a_test.rb'] }
174
174
 
175
175
  it 'returns exit code 0' do
176
176
  expect(KnapsackPro::Adapters::MinitestAdapter).to receive(:verify_bind_method_called)
@@ -185,8 +185,8 @@ describe KnapsackPro::Runners::Queue::MinitestRunner do
185
185
  end
186
186
  end
187
187
 
188
- context "when all_test_file_paths don't exist" do
189
- let(:all_test_file_paths) { [] }
188
+ context 'when node_test_file_paths do not exist' do
189
+ let(:node_test_file_paths) { [] }
190
190
 
191
191
  it 'returns exit code 0' do
192
192
  expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
@@ -24,7 +24,7 @@ describe KnapsackPro do
24
24
  })
25
25
 
26
26
  expect(Logger).to receive(:new).with('log/knapsack_pro_node_1.log').and_return(logger)
27
- expect(logger).to receive(:level=).with(Logger::DEBUG)
27
+ expect(logger).to receive(:level=).with(Logger::INFO)
28
28
  expect(KnapsackPro::LoggerWrapper).to receive(:new).with(logger).and_return(logger_wrapper)
29
29
  end
30
30
 
@@ -38,7 +38,7 @@ describe KnapsackPro do
38
38
  })
39
39
 
40
40
  expect(Logger).to receive(:new).with('log/knapsack_pro_node_0.log').and_return(logger)
41
- expect(logger).to receive(:level=).with(Logger::DEBUG)
41
+ expect(logger).to receive(:level=).with(Logger::INFO)
42
42
  expect(KnapsackPro::LoggerWrapper).to receive(:new).with(logger).and_return(logger_wrapper)
43
43
  end
44
44
 
@@ -51,7 +51,7 @@ describe KnapsackPro do
51
51
 
52
52
  before do
53
53
  expect(Logger).to receive(:new).with(STDOUT).and_return(logger)
54
- expect(logger).to receive(:level=).with(Logger::DEBUG)
54
+ expect(logger).to receive(:level=).with(Logger::INFO)
55
55
  expect(KnapsackPro::LoggerWrapper).to receive(:new).with(logger).and_return(logger_wrapper)
56
56
  end
57
57
 
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: 6.0.4
4
+ version: 7.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ArturT
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-09 00:00:00.000000000 Z
11
+ date: 2024-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -178,10 +178,10 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: 0.9.4
181
- description: Run tests in parallel across CI server nodes based on tests execution
182
- time. Split tests in a dynamic way to ensure parallel jobs are done at a similar
183
- time. Thanks to that your CI build time is as fast as possible. It works with many
184
- CI providers.
181
+ description: Knapsack Pro wraps your current test runner(s) and works with your existing
182
+ CI infrastructure to parallelize tests optimally. It dynamically splits your tests
183
+ based on up-to-date test execution data. It's designed from the ground up for CI
184
+ and supports all of them.
185
185
  email:
186
186
  - support@knapsackpro.com
187
187
  executables:
@@ -193,6 +193,7 @@ files:
193
193
  - ".github/assets/install-button.png"
194
194
  - ".github/assets/knapsack-diamonds.png"
195
195
  - ".github/dependabot.yml"
196
+ - ".github/pull_request_template.md"
196
197
  - ".gitignore"
197
198
  - ".rspec"
198
199
  - CHANGELOG.md
@@ -240,15 +241,15 @@ files:
240
241
  - lib/knapsack_pro/crypto/decryptor.rb
241
242
  - lib/knapsack_pro/crypto/digestor.rb
242
243
  - lib/knapsack_pro/crypto/encryptor.rb
244
+ - lib/knapsack_pro/extensions/rspec_extension.rb
243
245
  - lib/knapsack_pro/formatters/rspec_json_formatter.rb
244
- - lib/knapsack_pro/formatters/rspec_queue_profile_formatter_extension.rb
245
- - lib/knapsack_pro/formatters/rspec_queue_summary_formatter.rb
246
246
  - lib/knapsack_pro/formatters/time_tracker.rb
247
247
  - lib/knapsack_pro/formatters/time_tracker_fetcher.rb
248
248
  - lib/knapsack_pro/hooks/queue.rb
249
249
  - lib/knapsack_pro/logger_wrapper.rb
250
250
  - lib/knapsack_pro/mask_string.rb
251
251
  - lib/knapsack_pro/presenter.rb
252
+ - lib/knapsack_pro/pure/queue/rspec_pure.rb
252
253
  - lib/knapsack_pro/queue_allocator.rb
253
254
  - lib/knapsack_pro/queue_allocator_builder.rb
254
255
  - lib/knapsack_pro/railtie.rb
@@ -301,6 +302,8 @@ files:
301
302
  - spec/fixtures/vcr_cassettes/api/v1/build_subsets/create/success.yml
302
303
  - spec/integration/api/build_distributions_subset_spec.rb
303
304
  - spec/integration/api/build_subsets_create_spec.rb
305
+ - spec/integration/runners/queue/rspec_runner.rb
306
+ - spec/integration/runners/queue/rspec_runner_spec.rb
304
307
  - spec/knapsack_pro/adapters/base_adapter_spec.rb
305
308
  - spec/knapsack_pro/adapters/cucumber_adapter_spec.rb
306
309
  - spec/knapsack_pro/adapters/minitest_adapter_spec.rb
@@ -341,6 +344,7 @@ files:
341
344
  - spec/knapsack_pro/hooks/queue_spec.rb
342
345
  - spec/knapsack_pro/logger_wrapper_spec.rb
343
346
  - spec/knapsack_pro/presenter_spec.rb
347
+ - spec/knapsack_pro/pure/queue/rspec_pure_spec.rb
344
348
  - spec/knapsack_pro/queue_allocator_builder_spec.rb
345
349
  - spec/knapsack_pro/queue_allocator_spec.rb
346
350
  - spec/knapsack_pro/report_spec.rb
@@ -354,7 +358,6 @@ files:
354
358
  - spec/knapsack_pro/runners/queue/base_runner_spec.rb
355
359
  - spec/knapsack_pro/runners/queue/cucumber_runner_spec.rb
356
360
  - spec/knapsack_pro/runners/queue/minitest_runner_spec.rb
357
- - spec/knapsack_pro/runners/queue/rspec_runner_spec.rb
358
361
  - spec/knapsack_pro/runners/rspec_runner_spec.rb
359
362
  - spec/knapsack_pro/runners/spinach_runner_spec.rb
360
363
  - spec/knapsack_pro/runners/test_unit_runner_spec.rb
@@ -401,14 +404,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
401
404
  requirements:
402
405
  - - ">="
403
406
  - !ruby/object:Gem::Version
404
- version: '0'
407
+ version: 2.7.0
405
408
  required_rubygems_version: !ruby/object:Gem::Requirement
406
409
  requirements:
407
410
  - - ">="
408
411
  - !ruby/object:Gem::Version
409
412
  version: '0'
410
413
  requirements: []
411
- rubygems_version: 3.4.10
414
+ rubygems_version: 3.4.19
412
415
  signing_key:
413
416
  specification_version: 4
414
417
  summary: Knapsack Pro splits tests across parallel CI nodes and ensures each parallel
@@ -421,6 +424,8 @@ test_files:
421
424
  - spec/fixtures/vcr_cassettes/api/v1/build_subsets/create/success.yml
422
425
  - spec/integration/api/build_distributions_subset_spec.rb
423
426
  - spec/integration/api/build_subsets_create_spec.rb
427
+ - spec/integration/runners/queue/rspec_runner.rb
428
+ - spec/integration/runners/queue/rspec_runner_spec.rb
424
429
  - spec/knapsack_pro/adapters/base_adapter_spec.rb
425
430
  - spec/knapsack_pro/adapters/cucumber_adapter_spec.rb
426
431
  - spec/knapsack_pro/adapters/minitest_adapter_spec.rb
@@ -461,6 +466,7 @@ test_files:
461
466
  - spec/knapsack_pro/hooks/queue_spec.rb
462
467
  - spec/knapsack_pro/logger_wrapper_spec.rb
463
468
  - spec/knapsack_pro/presenter_spec.rb
469
+ - spec/knapsack_pro/pure/queue/rspec_pure_spec.rb
464
470
  - spec/knapsack_pro/queue_allocator_builder_spec.rb
465
471
  - spec/knapsack_pro/queue_allocator_spec.rb
466
472
  - spec/knapsack_pro/report_spec.rb
@@ -474,7 +480,6 @@ test_files:
474
480
  - spec/knapsack_pro/runners/queue/base_runner_spec.rb
475
481
  - spec/knapsack_pro/runners/queue/cucumber_runner_spec.rb
476
482
  - spec/knapsack_pro/runners/queue/minitest_runner_spec.rb
477
- - spec/knapsack_pro/runners/queue/rspec_runner_spec.rb
478
483
  - spec/knapsack_pro/runners/rspec_runner_spec.rb
479
484
  - spec/knapsack_pro/runners/spinach_runner_spec.rb
480
485
  - spec/knapsack_pro/runners/test_unit_runner_spec.rb
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec::Support.require_rspec_core('formatters/profile_formatter')
4
-
5
- module KnapsackPro
6
- module Formatters
7
- module RSpecQueueProfileFormatterExtension
8
- def self.print_summary
9
- return unless KnapsackPro::Config::Env.modify_default_rspec_formatters?
10
- ::RSpec::Core::Formatters::ProfileFormatter.print_profile_summary
11
- end
12
-
13
- def initialize(output)
14
- @output = output
15
- self.class.registered_output = output
16
- end
17
-
18
- def dump_profile(profile)
19
- self.class.most_recent_profile = profile
20
- end
21
- end
22
- end
23
- end
24
-
25
- if KnapsackPro::Config::Env.modify_default_rspec_formatters?
26
- class RSpec::Core::Formatters::ProfileFormatter
27
- prepend KnapsackPro::Formatters::RSpecQueueProfileFormatterExtension
28
-
29
- def self.registered_output=(output)
30
- @registered_output = {
31
- ENV['KNAPSACK_PRO_QUEUE_ID'] => output
32
- }
33
- end
34
-
35
- def self.registered_output
36
- @registered_output ||= {}
37
- @registered_output[ENV['KNAPSACK_PRO_QUEUE_ID']]
38
- end
39
-
40
- def self.most_recent_profile=(profile)
41
- @most_recent_profile = {
42
- ENV['KNAPSACK_PRO_QUEUE_ID'] => profile
43
- }
44
- end
45
-
46
- def self.most_recent_profile
47
- @most_recent_profile ||= {}
48
- @most_recent_profile[ENV['KNAPSACK_PRO_QUEUE_ID']] || []
49
- end
50
-
51
- def self.print_profile_summary
52
- return unless registered_output
53
- profile_formatter = new(registered_output)
54
- profile_formatter.send(:dump_profile_slowest_examples, most_recent_profile)
55
- profile_formatter.send(:dump_profile_slowest_example_groups, most_recent_profile)
56
- end
57
- end
58
- end
@@ -1,145 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative './time_tracker_fetcher'
4
-
5
- RSpec::Support.require_rspec_core('formatters/base_formatter')
6
- RSpec::Support.require_rspec_core('formatters/base_text_formatter')
7
-
8
- module KnapsackPro
9
- module Formatters
10
- module RSpecHideFailuresAndPendingExtension
11
- def dump_failures(notification); end
12
- def dump_pending(notification); end
13
- def dump_summary(summary); end
14
- end
15
-
16
- class RSpecQueueSummaryFormatter < ::RSpec::Core::Formatters::BaseFormatter
17
- ::RSpec::Core::Formatters.register self, :dump_summary, :dump_failures, :dump_pending
18
-
19
- def self.registered_output=(output)
20
- @registered_output = {
21
- ENV['KNAPSACK_PRO_QUEUE_ID'] => output
22
- }
23
- end
24
-
25
- def self.registered_output
26
- @registered_output[ENV['KNAPSACK_PRO_QUEUE_ID']]
27
- end
28
-
29
- def self.most_recent_failures_summary=(fully_formatted_failed_examples)
30
- @most_recent_failures_summary = {
31
- ENV['KNAPSACK_PRO_QUEUE_ID'] => fully_formatted_failed_examples
32
- }
33
- end
34
-
35
- def self.most_recent_failures_summary
36
- @most_recent_failures_summary ||= {}
37
- @most_recent_failures_summary[ENV['KNAPSACK_PRO_QUEUE_ID']] || []
38
- end
39
-
40
- def self.most_recent_pending=(fully_formatted_pending_examples)
41
- @most_recent_pending = {
42
- ENV['KNAPSACK_PRO_QUEUE_ID'] => fully_formatted_pending_examples
43
- }
44
- end
45
-
46
- def self.most_recent_pending
47
- @most_recent_pending ||= {}
48
- @most_recent_pending[ENV['KNAPSACK_PRO_QUEUE_ID']] || []
49
- end
50
-
51
- def self.most_recent_summary=(fully_formatted)
52
- @most_recent_summary = {
53
- ENV['KNAPSACK_PRO_QUEUE_ID'] => fully_formatted
54
- }
55
- end
56
-
57
- def self.most_recent_summary
58
- @most_recent_summary ||= {}
59
- @most_recent_summary[ENV['KNAPSACK_PRO_QUEUE_ID']] || []
60
- end
61
-
62
- def self.print_summary
63
- registered_output.puts('Knapsack Pro Queue finished!')
64
- registered_output.puts('')
65
-
66
- unless most_recent_pending.empty?
67
- registered_output.puts('All pending tests on this CI node:')
68
- registered_output.puts(most_recent_pending)
69
- registered_output.puts('')
70
- end
71
-
72
- unless most_recent_failures_summary.empty?
73
- registered_output.puts('All failed tests on this CI node:')
74
- registered_output.puts(most_recent_failures_summary)
75
- registered_output.puts('')
76
- end
77
-
78
- registered_output.puts(most_recent_summary)
79
- end
80
-
81
- def self.print_exit_summary(all_test_file_paths)
82
- registered_output.puts('Knapsack Pro Queue exited/aborted!')
83
- registered_output.puts('')
84
-
85
- time_tracker = KnapsackPro::Formatters::TimeTrackerFetcher.call
86
- unexecuted_test_files = time_tracker&.unexecuted_test_files(all_test_file_paths) || []
87
- unless unexecuted_test_files.empty?
88
- registered_output.puts('Unexecuted tests on this CI node:')
89
- registered_output.puts(unexecuted_test_files)
90
- registered_output.puts('')
91
- end
92
-
93
- unless most_recent_pending.empty?
94
- registered_output.puts('All pending tests on this CI node:')
95
- registered_output.puts(most_recent_pending)
96
- registered_output.puts('')
97
- end
98
-
99
- unless most_recent_failures_summary.empty?
100
- registered_output.puts('All failed tests on this CI node:')
101
- registered_output.puts(most_recent_failures_summary)
102
- registered_output.puts('')
103
- end
104
-
105
- registered_output.puts(most_recent_summary)
106
- end
107
-
108
- def initialize(output)
109
- super
110
- self.class.registered_output = output
111
- end
112
-
113
- def dump_failures(notification)
114
- return if notification.failure_notifications.empty?
115
- self.class.most_recent_failures_summary = notification.fully_formatted_failed_examples
116
- end
117
-
118
- def dump_pending(notification)
119
- return if notification.pending_examples.empty?
120
- self.class.most_recent_pending = notification.fully_formatted_pending_examples
121
- end
122
-
123
- def dump_summary(summary)
124
- colorizer = ::RSpec::Core::Formatters::ConsoleCodes
125
- duration = KnapsackPro::Formatters::TimeTrackerFetcher.call.duration
126
- formatted_duration = ::RSpec::Core::Formatters::Helpers.format_duration(duration)
127
-
128
- formatted = "\nFinished in #{formatted_duration}\n" \
129
- "#{summary.colorized_totals_line(colorizer)}\n"
130
-
131
- unless summary.failed_examples.empty?
132
- formatted += (summary.colorized_rerun_commands(colorizer) + "\n")
133
- end
134
-
135
- self.class.most_recent_summary = formatted
136
- end
137
- end
138
- end
139
- end
140
-
141
- if KnapsackPro::Config::Env.modify_default_rspec_formatters?
142
- class RSpec::Core::Formatters::BaseTextFormatter
143
- prepend KnapsackPro::Formatters::RSpecHideFailuresAndPendingExtension
144
- end
145
- end