knapsack_pro 6.0.4 → 7.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) 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 +95 -0
  6. data/Gemfile +9 -0
  7. data/README.md +7 -9
  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 +24 -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 +100 -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 +127 -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 +2405 -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 +56 -24
  30. data/spec/knapsack_pro/config/env_spec.rb +1 -35
  31. data/spec/knapsack_pro/formatters/time_tracker_fetcher_spec.rb +30 -0
  32. data/spec/knapsack_pro/formatters/time_tracker_specs.rb +8 -37
  33. data/spec/knapsack_pro/hooks/queue_spec.rb +2 -2
  34. data/spec/knapsack_pro/presenter_spec.rb +1 -1
  35. data/spec/knapsack_pro/pure/queue/rspec_pure_spec.rb +248 -0
  36. data/spec/knapsack_pro/runners/queue/cucumber_runner_spec.rb +16 -16
  37. data/spec/knapsack_pro/runners/queue/minitest_runner_spec.rb +14 -14
  38. data/spec/knapsack_pro_spec.rb +3 -3
  39. metadata +19 -12
  40. data/lib/knapsack_pro/formatters/rspec_queue_profile_formatter_extension.rb +0 -58
  41. data/lib/knapsack_pro/formatters/rspec_queue_summary_formatter.rb +0 -145
  42. data/spec/knapsack_pro/runners/queue/rspec_runner_spec.rb +0 -536
@@ -4,223 +4,177 @@ module KnapsackPro
4
4
  module Runners
5
5
  module Queue
6
6
  class RSpecRunner < BaseRunner
7
- @@used_seed = nil
8
-
9
- def self.run(args)
7
+ def self.run(args, stream_error = $stderr, stream_out = $stdout)
10
8
  require 'rspec/core'
9
+ require_relative '../../extensions/rspec_extension'
11
10
  require_relative '../../formatters/time_tracker'
12
11
  require_relative '../../formatters/time_tracker_fetcher'
13
- require_relative '../../formatters/rspec_queue_summary_formatter'
14
- require_relative '../../formatters/rspec_queue_profile_formatter_extension'
12
+
13
+ KnapsackPro::Extensions::RSpecExtension.setup!
15
14
 
16
15
  ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN'] = KnapsackPro::Config::Env.test_suite_token_rspec
17
- ENV['KNAPSACK_PRO_QUEUE_RECORDING_ENABLED'] = 'true'
18
- ENV['KNAPSACK_PRO_QUEUE_ID'] = KnapsackPro::Config::EnvGenerator.set_queue_id
19
16
 
20
- KnapsackPro::Config::Env.set_test_runner_adapter(adapter_class)
21
- runner = new(adapter_class)
22
-
23
- cli_args = (args || '').split
24
- adapter_class.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(cli_args)
25
-
26
- # when format option is not defined by user then use progress formatter to show tests execution progress
27
- cli_args += ['--format', 'progress'] unless adapter_class.has_format_option?(cli_args)
28
-
29
- cli_args += [
30
- # shows summary of all tests executed in Queue Mode at the very end
31
- '--format', KnapsackPro::Formatters::RSpecQueueSummaryFormatter.to_s,
32
- '--format', KnapsackPro::Formatters::TimeTracker.to_s,
33
- '--default-path', runner.test_dir,
34
- ]
35
-
36
- accumulator = {
37
- status: :next,
38
- runner: runner,
39
- can_initialize_queue: true,
40
- args: cli_args,
41
- exitstatus: 0,
42
- all_test_file_paths: [],
43
- }
44
- while accumulator[:status] == :next
45
- handle_signal!
46
- accumulator = run_tests(accumulator)
47
- end
17
+ rspec_pure = KnapsackPro::Pure::Queue::RSpecPure.new
48
18
 
49
- Kernel.exit(accumulator[:exitstatus])
19
+ queue_runner = new(KnapsackPro::Adapters::RSpecAdapter, rspec_pure, args, stream_error, stream_out)
20
+ queue_runner.run
50
21
  end
51
22
 
52
- def self.run_tests(accumulator)
53
- runner = accumulator.fetch(:runner)
54
- can_initialize_queue = accumulator.fetch(:can_initialize_queue)
55
- args = accumulator.fetch(:args)
56
- exitstatus = accumulator.fetch(:exitstatus)
57
- all_test_file_paths = accumulator.fetch(:all_test_file_paths)
23
+ def initialize(adapter_class, rspec_pure, args, stream_error, stream_out)
24
+ super(adapter_class)
25
+ @adapter_class = adapter_class
26
+ @rspec_pure = rspec_pure
27
+ args_array = (args || '').split
28
+ has_format_option = @adapter_class.has_format_option?(args_array)
29
+ has_require_rails_helper_option = @adapter_class.has_require_rails_helper_option?(args_array)
30
+ rails_helper_exists = @adapter_class.rails_helper_exists?(test_dir)
31
+ @cli_args = rspec_pure.prepare_cli_args(args, has_format_option, has_require_rails_helper_option, rails_helper_exists, test_dir)
32
+ @stream_error = stream_error
33
+ @stream_out = stream_out
34
+ @node_test_file_paths = []
35
+ @rspec_runner = nil # RSpec::Core::Runner is lazy initialized
36
+ end
58
37
 
59
- test_file_paths = runner.test_file_paths(
60
- can_initialize_queue: can_initialize_queue,
61
- executed_test_files: all_test_file_paths
62
- )
38
+ # Based on:
39
+ # https://github.com/rspec/rspec-core/blob/f8c8880dabd8f0544a6f91d8d4c857c1bd8df903/lib/rspec/core/runner.rb#L85
40
+ #
41
+ # @return [Fixnum] exit status code.
42
+ # 0 if all specs passed,
43
+ # or the configured failure exit code (1 by default) if specs failed.
44
+ def run
45
+ pre_run_setup
46
+
47
+ if @rspec_runner.knapsack__wants_to_quit?
48
+ exit_code = @rspec_runner.knapsack__exit_early
49
+ Kernel.exit(exit_code)
50
+ end
51
+
52
+ begin
53
+ exit_code = @rspec_runner.knapsack__run_specs(self)
54
+ rescue KnapsackPro::Runners::Queue::BaseRunner::TerminationError
55
+ exit_code = @rspec_pure.error_exit_code(@rspec_runner.knapsack__error_exit_code)
56
+ Kernel.exit(exit_code)
57
+ rescue Exception => exception
58
+ KnapsackPro.logger.error("An unexpected exception happened. RSpec cannot handle it. The exception: #{exception.inspect}")
63
59
 
64
- if test_file_paths.empty?
65
- unless all_test_file_paths.empty?
66
- KnapsackPro::Adapters::RSpecAdapter.verify_bind_method_called
60
+ message = @rspec_pure.exit_summary(unexecuted_test_files)
61
+ KnapsackPro.logger.warn(message) if message
67
62
 
68
- KnapsackPro::Formatters::RSpecQueueSummaryFormatter.print_summary
69
- KnapsackPro::Formatters::RSpecQueueProfileFormatterExtension.print_summary
63
+ exit_code = @rspec_pure.error_exit_code(@rspec_runner.knapsack__error_exit_code)
64
+ Kernel.exit(exit_code)
65
+ end
70
66
 
71
- args += ['--seed', @@used_seed] if @@used_seed
67
+ post_run_tasks(exit_code)
68
+ end
72
69
 
73
- log_rspec_command(args, all_test_file_paths, :end_of_queue)
74
- end
70
+ def with_batch
71
+ can_initialize_queue = true
75
72
 
76
- KnapsackPro::Hooks::Queue.call_after_queue
73
+ loop do
74
+ handle_signal!
75
+ test_file_paths = pull_tests_from_queue(can_initialize_queue: can_initialize_queue)
76
+ can_initialize_queue = false
77
77
 
78
- time_tracker = KnapsackPro::Formatters::TimeTrackerFetcher.call
79
- KnapsackPro::Report.save_node_queue_to_api(time_tracker&.queue(all_test_file_paths) || [])
78
+ break if test_file_paths.empty?
80
79
 
81
- return {
82
- status: :completed,
83
- exitstatus: exitstatus,
84
- }
85
- else
86
80
  subset_queue_id = KnapsackPro::Config::EnvGenerator.set_subset_queue_id
87
81
  ENV['KNAPSACK_PRO_SUBSET_QUEUE_ID'] = subset_queue_id
88
82
 
89
83
  KnapsackPro::Hooks::Queue.call_before_subset_queue
90
84
 
91
- all_test_file_paths += test_file_paths
92
- cli_args = args + test_file_paths
93
-
94
- ensure_spec_opts_have_knapsack_pro_formatters
95
- options = ::RSpec::Core::ConfigurationOptions.new(cli_args)
96
- rspec_runner = ::RSpec::Core::Runner.new(options)
97
-
98
- begin
99
- exit_code = rspec_runner.run($stderr, $stdout)
100
- exitstatus = exit_code if exit_code != 0
101
- rescue Exception => exception
102
- KnapsackPro.logger.error("Having exception when running RSpec: #{exception.inspect}")
103
- KnapsackPro::Formatters::RSpecQueueSummaryFormatter.print_exit_summary(all_test_file_paths)
104
- KnapsackPro::Hooks::Queue.call_after_subset_queue
105
- KnapsackPro::Hooks::Queue.call_after_queue
106
- Kernel.exit(1)
107
- raise
108
- else
109
- if rspec_runner.world.wants_to_quit
110
- KnapsackPro.logger.warn('RSpec wants to quit.')
111
- set_terminate_process
112
- end
113
- if rspec_runner.world.respond_to?(:rspec_is_quitting) && rspec_runner.world.rspec_is_quitting
114
- KnapsackPro.logger.warn('RSpec is quitting.')
115
- set_terminate_process
116
- end
117
-
118
- printable_args = args_with_seed_option_added_when_viable(args, rspec_runner)
119
- log_rspec_command(printable_args, test_file_paths, :subset_queue)
120
-
121
- rspec_clear_examples
122
-
123
- KnapsackPro::Hooks::Queue.call_after_subset_queue
124
-
125
- return {
126
- status: :next,
127
- runner: runner,
128
- can_initialize_queue: false,
129
- args: args,
130
- exitstatus: exitstatus,
131
- all_test_file_paths: all_test_file_paths,
132
- }
133
- end
134
- end
135
- end
85
+ yield test_file_paths
136
86
 
137
- def self.ensure_spec_opts_have_knapsack_pro_formatters
138
- return unless ENV['SPEC_OPTS']
87
+ KnapsackPro::Hooks::Queue.call_after_subset_queue
139
88
 
140
- if [
141
- ENV['SPEC_OPTS'].include?(KnapsackPro::Formatters::RSpecQueueSummaryFormatter.to_s),
142
- ENV['SPEC_OPTS'].include?(KnapsackPro::Formatters::TimeTracker.to_s),
143
- ].all?
144
- return
145
- end
89
+ if @rspec_runner.knapsack__wants_to_quit?
90
+ KnapsackPro.logger.warn('RSpec wants to quit.')
91
+ set_terminate_process
92
+ end
93
+ if @rspec_runner.knapsack__rspec_is_quitting?
94
+ KnapsackPro.logger.warn('RSpec is quitting.')
95
+ set_terminate_process
96
+ end
146
97
 
147
- unless ENV['SPEC_OPTS'].include?(KnapsackPro::Formatters::RSpecQueueSummaryFormatter.to_s)
148
- ENV['SPEC_OPTS'] = "#{ENV['SPEC_OPTS']} --format #{KnapsackPro::Formatters::RSpecQueueSummaryFormatter}"
98
+ log_rspec_batch_command(test_file_paths)
149
99
  end
100
+ end
150
101
 
151
- unless ENV['SPEC_OPTS'].include?(KnapsackPro::Formatters::TimeTracker.to_s)
152
- ENV['SPEC_OPTS'] = "#{ENV['SPEC_OPTS']} --format #{KnapsackPro::Formatters::TimeTracker}"
153
- end
102
+ def handle_signal!
103
+ self.class.handle_signal!
104
+ end
105
+
106
+ def log_fail_fast_limit_met
107
+ KnapsackPro.logger.warn('Test execution has been canceled because the RSpec --fail-fast option is enabled. It will cause other CI nodes to run tests longer because they need to consume more tests from the Knapsack Pro Queue API.')
154
108
  end
155
109
 
156
110
  private
157
111
 
158
- def self.adapter_class
159
- KnapsackPro::Adapters::RSpecAdapter
112
+ def pre_run_setup
113
+ ENV['KNAPSACK_PRO_QUEUE_RECORDING_ENABLED'] = 'true'
114
+ ENV['KNAPSACK_PRO_QUEUE_ID'] = KnapsackPro::Config::EnvGenerator.set_queue_id
115
+
116
+ KnapsackPro::Config::Env.set_test_runner_adapter(@adapter_class)
117
+
118
+ ENV['SPEC_OPTS'] = @rspec_pure.add_knapsack_pro_formatters_to(ENV['SPEC_OPTS'])
119
+ @adapter_class.ensure_no_tag_option_when_rspec_split_by_test_examples_enabled!(@cli_args)
120
+
121
+ rspec_configuration_options = ::RSpec::Core::ConfigurationOptions.new(@cli_args)
122
+ @rspec_runner = ::RSpec::Core::Runner.new(rspec_configuration_options)
123
+ @rspec_runner.knapsack__setup(@stream_error, @stream_out)
124
+
125
+ ensure_no_deprecated_run_all_when_everything_filtered_option!
160
126
  end
161
127
 
162
- def self.log_rspec_command(cli_args, test_file_paths, type)
163
- case type
164
- when :subset_queue
165
- KnapsackPro.logger.info("To retry the last batch of tests fetched from the API Queue, please run the following command on your machine:")
166
- when :end_of_queue
167
- KnapsackPro.logger.info("To retry all the tests assigned to this CI node, please run the following command on your machine:")
168
- end
128
+ def post_run_tasks(exit_code)
129
+ @adapter_class.verify_bind_method_called
169
130
 
170
- stringified_cli_args = cli_args.join(' ')
171
- .sub(" --format #{KnapsackPro::Formatters::RSpecQueueSummaryFormatter}", '')
172
- .sub(" --format #{KnapsackPro::Formatters::TimeTracker}", '')
131
+ log_rspec_queue_command
173
132
 
174
- KnapsackPro.logger.info(
175
- "bundle exec rspec #{stringified_cli_args} " +
176
- KnapsackPro::TestFilePresenter.stringify_paths(test_file_paths)
177
- )
133
+ time_tracker = KnapsackPro::Formatters::TimeTrackerFetcher.call
134
+ KnapsackPro::Report.save_node_queue_to_api(time_tracker&.queue(@node_test_file_paths))
135
+
136
+ Kernel.exit(exit_code)
178
137
  end
179
138
 
180
- # Clear rspec examples without the shared examples:
181
- # https://github.com/rspec/rspec-core/pull/2379
182
- #
183
- # Keep formatters and report to accumulate info about failed/pending tests
184
- def self.rspec_clear_examples
185
- if ::RSpec::ExampleGroups.respond_to?(:remove_all_constants)
186
- ::RSpec::ExampleGroups.remove_all_constants
187
- else
188
- ::RSpec::ExampleGroups.constants.each do |constant|
189
- ::RSpec::ExampleGroups.__send__(:remove_const, constant)
190
- end
191
- end
192
- ::RSpec.world.example_groups.clear
193
- ::RSpec.configuration.start_time = ::RSpec::Core::Time.now
194
-
195
- if KnapsackPro::Config::Env.rspec_split_by_test_examples?
196
- # Reset example group counts to ensure scoped example ids in metadata
197
- # have correct index (not increased by each subsequent run).
198
- # Solves this problem: https://github.com/rspec/rspec-core/issues/2721
199
- ::RSpec.world.instance_variable_set(:@example_group_counts_by_spec_file, Hash.new(0))
200
- end
139
+ def ensure_no_deprecated_run_all_when_everything_filtered_option!
140
+ return unless @rspec_runner.knapsack__deprecated_run_all_when_everything_filtered_enabled?
201
141
 
202
- # skip reset filters for old RSpec versions
203
- if ::RSpec.configuration.respond_to?(:reset_filters)
204
- ::RSpec.configuration.reset_filters
205
- end
142
+ error_message = "The run_all_when_everything_filtered option is deprecated. See: #{KnapsackPro::Urls::RSPEC__DEPRECATED_RUN_ALL_WHEN_EVERYTHING_FILTERED}"
143
+ KnapsackPro.logger.error(error_message)
144
+ raise error_message
206
145
  end
207
146
 
208
- def self.args_with_seed_option_added_when_viable(args, rspec_runner)
209
- order_option = adapter_class.order_option(args)
147
+ def pull_tests_from_queue(can_initialize_queue: false)
148
+ test_file_paths = test_file_paths(
149
+ can_initialize_queue: can_initialize_queue,
150
+ executed_test_files: @node_test_file_paths
151
+ )
152
+ @node_test_file_paths += test_file_paths
153
+ test_file_paths
154
+ end
210
155
 
211
- if order_option
212
- # Don't add the seed option for order other than random, e.g. `defined`
213
- return args unless order_option.include?('rand')
214
- # Don't add the seed option if the seed is already set in args, e.g. `rand:12345`
215
- return args if order_option.to_s.split(':')[1]
216
- end
156
+ def log_rspec_batch_command(test_file_paths)
157
+ order_option = @adapter_class.order_option(@cli_args)
158
+ printable_args = @rspec_pure.args_with_seed_option_added_when_viable(order_option, @rspec_runner.knapsack__seed, @cli_args)
159
+ messages = @rspec_pure.rspec_command(printable_args, test_file_paths, :batch_finished)
160
+ log_info_messages(messages)
161
+ end
217
162
 
218
- # Don't add the seed option if the seed was not used (i.e. a different order is being used, e.g. `defined`)
219
- return args unless rspec_runner.configuration.seed_used?
163
+ def log_rspec_queue_command
164
+ order_option = @adapter_class.order_option(@cli_args)
165
+ printable_args = @rspec_pure.args_with_seed_option_added_when_viable(order_option, @rspec_runner.knapsack__seed, @cli_args)
166
+ messages = @rspec_pure.rspec_command(printable_args, @node_test_file_paths, :queue_finished)
167
+ log_info_messages(messages)
168
+ end
220
169
 
221
- @@used_seed = rspec_runner.configuration.seed.to_s
170
+ def log_info_messages(messages)
171
+ messages.each do |message|
172
+ KnapsackPro.logger.info(message)
173
+ end
174
+ end
222
175
 
223
- args + ['--seed', @@used_seed]
176
+ def unexecuted_test_files
177
+ KnapsackPro::Formatters::TimeTrackerFetcher.unexecuted_test_files(@node_test_file_paths)
224
178
  end
225
179
  end
226
180
  end
@@ -28,6 +28,8 @@ module KnapsackPro
28
28
 
29
29
  REGULAR_MODE__CONNECTION_ERROR_WITH_FALLBACK_ENABLED_TRUE_AND_POSITIVE_RETRY_COUNT = "#{HOST}/perma/ruby/regular-mode-connection-error-with-fallback-enabled-true-and-positive-retry-count"
30
30
 
31
+ RSPEC__DEPRECATED_RUN_ALL_WHEN_EVERYTHING_FILTERED = "#{HOST}/perma/ruby/rspec-deprecated-run-all-when-everything-filtered"
32
+
31
33
  RSPEC__SKIPS_TESTS = "#{HOST}/perma/ruby/rspec-skips-tests"
32
34
 
33
35
  RSPEC__SPLIT_BY_TEST_EXAMPLES__TAG = "#{HOST}/perma/ruby/rspec-split-by-test-examples-tag"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KnapsackPro
4
- VERSION = '6.0.4'
4
+ VERSION = '7.0.1'
5
5
  end
data/lib/knapsack_pro.rb CHANGED
@@ -82,6 +82,7 @@ require_relative 'knapsack_pro/crypto/encryptor'
82
82
  require_relative 'knapsack_pro/crypto/branch_encryptor'
83
83
  require_relative 'knapsack_pro/crypto/decryptor'
84
84
  require_relative 'knapsack_pro/crypto/digestor'
85
+ require_relative 'knapsack_pro/pure/queue/rspec_pure'
85
86
 
86
87
  require 'knapsack_pro/railtie' if defined?(Rails::Railtie)
87
88
 
@@ -0,0 +1,80 @@
1
+ require 'knapsack_pro'
2
+ require 'json'
3
+
4
+ ENV['KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC'] = SecureRandom.hex
5
+ ENV['KNAPSACK_PRO_CI_NODE_BUILD_ID'] = SecureRandom.uuid
6
+ ENV['KNAPSACK_PRO_TEST_DIR'] = 'spec_integration'
7
+ ENV['KNAPSACK_PRO_TEST_FILE_PATTERN'] = "spec_integration/**{,/*/**}/*_spec.rb"
8
+
9
+ RSPEC_OPTIONS = ENV.fetch('TEST__RSPEC_OPTIONS')
10
+ SHOW_DEBUG_LOG = ENV['TEST__SHOW_DEBUG_LOG'] == 'true'
11
+ SPEC_BATCHES = JSON.load(ENV.fetch('TEST__SPEC_BATCHES'))
12
+
13
+ class IntegrationTestLogger
14
+ def self.log(message)
15
+ puts "[INTEGRATION TEST] #{message}"
16
+ end
17
+ end
18
+
19
+ module KnapsackProExtensions
20
+ module QueueAllocatorExtension
21
+ def test_file_paths(can_initialize_queue, executed_test_files)
22
+ @batch_index ||= 0
23
+ last_batch = []
24
+ batches = [*SPEC_BATCHES, last_batch]
25
+ tests = batches[@batch_index]
26
+ @batch_index += 1
27
+
28
+ if SHOW_DEBUG_LOG
29
+ IntegrationTestLogger.log("Stubbed tests from the Queue API: #{tests.inspect}")
30
+ end
31
+
32
+ tests
33
+ end
34
+ end
35
+
36
+ module Report
37
+ def create_build_subset(test_files)
38
+ if ENV['TEST__LOG_EXECUTION_TIMES']
39
+ have_execution_time = test_files.all? { _1.fetch('time_execution') > 0 }
40
+ IntegrationTestLogger.log("test_files: #{test_files.size}, test files have execution time: #{have_execution_time}")
41
+ end
42
+
43
+ return unless SHOW_DEBUG_LOG
44
+ IntegrationTestLogger.log("Stubbed the #{__method__} method")
45
+ end
46
+ end
47
+
48
+ module RSpecAdapter
49
+ def test_file_cases_for(slow_test_files)
50
+ IntegrationTestLogger.log("Stubbed test file cases for slow test files: #{slow_test_files}")
51
+
52
+ test_file_paths = JSON.load(ENV.fetch('TEST__TEST_FILE_CASES_FOR_SLOW_TEST_FILES'))
53
+ test_file_paths.map do |path|
54
+ { 'path' => path }
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ KnapsackPro::QueueAllocator.prepend(KnapsackProExtensions::QueueAllocatorExtension)
61
+
62
+ module KnapsackPro
63
+ class Report
64
+ class << self
65
+ prepend KnapsackProExtensions::Report
66
+ end
67
+ end
68
+ end
69
+
70
+ module KnapsackPro
71
+ module Adapters
72
+ class RSpecAdapter
73
+ class << self
74
+ prepend KnapsackProExtensions::RSpecAdapter
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ KnapsackPro::Runners::Queue::RSpecRunner.run(RSPEC_OPTIONS)