knapsack_pro 5.3.3 → 5.3.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 388e3d47f2da2b0d9f1377677b912a44af5919111a86869115713488a83d84e2
4
- data.tar.gz: '08fd59b79cc652a4045f11f24a363cac8928644a2cf2a705b766e558e77d104f'
3
+ metadata.gz: 202eb37b7550c8556fadd902ed204ea71d5c928b2ed79f3452aa2f7dabee1a35
4
+ data.tar.gz: 846ec0dd9f9953bbbfeed2b9f77535a25e5182de8b3798dcff88a48fce1ba0f9
5
5
  SHA512:
6
- metadata.gz: 881dc5a753a3af8ffc1320eab7dd5a50ba38909812e971a1aeb2e282a3566f27afea3b601d99784d27d9959d7cf13f2d93b8db7634f73ccfb72a82b33e4243b2
7
- data.tar.gz: d7887b2f0bb7854b1d926f422b70ab1e4ac21904026e01863aa9b83e7a690a4df0d576f6ed863fe86e8f9dfb574db106553a7a61fc0913b1dc26ac22903c422b
6
+ metadata.gz: 6e9e1bffd253bade681efd59cdb43a13c8ae99bb43981dbf8aaea0f7adc3e5d2cce530488e6308a7eb35821abfc9245f26236e3e3dc323b68dbd3fd457905865
7
+ data.tar.gz: aedf904bdf8f765e1fdcbe651ee9d1f839201c48fdad7750668c88cb2f70bb1f61fff1fa633062f0be3bf31770656d48b0467b61b970f6d03526c430b7dc12c8
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ### 5.3.5
4
+
5
+ * Handle RSpec exceptions when running RSpec in Queue Mode
6
+
7
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/214
8
+
9
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/215
10
+
11
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v5.3.4...v5.3.5
12
+
13
+ ### 5.3.4
14
+
15
+ * fix(Queue Mode): handle OS signals and RSpec internal `wants_to_quit` and `rspec_is_quitting` states to stop consuming tests from the Queue API when the CI node is terminated
16
+
17
+ https://github.com/KnapsackPro/knapsack_pro-ruby/pull/207
18
+
19
+ https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v5.3.3...v5.3.4
20
+
3
21
  ### 5.3.3
4
22
 
5
23
  * Fix hanging CI when `git fetch --shallow-since` takes too long
@@ -62,11 +62,39 @@ module KnapsackPro
62
62
  unless most_recent_pending.empty?
63
63
  registered_output.puts('All pending tests on this CI node:')
64
64
  registered_output.puts(most_recent_pending)
65
+ registered_output.puts('')
65
66
  end
66
67
 
67
68
  unless most_recent_failures_summary.empty?
68
69
  registered_output.puts('All failed tests on this CI node:')
69
70
  registered_output.puts(most_recent_failures_summary)
71
+ registered_output.puts('')
72
+ end
73
+
74
+ registered_output.puts(most_recent_summary)
75
+ end
76
+
77
+ def self.print_exit_summary
78
+ registered_output.puts('Knapsack Pro Queue exited/aborted!')
79
+ registered_output.puts('')
80
+
81
+ unexecuted_test_files = KnapsackPro.tracker.unexecuted_test_files
82
+ unless unexecuted_test_files.empty?
83
+ registered_output.puts('Unexecuted tests on this CI node:')
84
+ registered_output.puts(unexecuted_test_files)
85
+ registered_output.puts('')
86
+ end
87
+
88
+ unless most_recent_pending.empty?
89
+ registered_output.puts('All pending tests on this CI node:')
90
+ registered_output.puts(most_recent_pending)
91
+ registered_output.puts('')
92
+ end
93
+
94
+ unless most_recent_failures_summary.empty?
95
+ registered_output.puts('All failed tests on this CI node:')
96
+ registered_output.puts(most_recent_failures_summary)
97
+ registered_output.puts('')
70
98
  end
71
99
 
72
100
  registered_output.puts(most_recent_summary)
@@ -2,6 +2,10 @@ module KnapsackPro
2
2
  module Runners
3
3
  module Queue
4
4
  class BaseRunner
5
+ TERMINATION_SIGNALS = %w(HUP INT TERM ABRT QUIT USR1 USR2)
6
+
7
+ @@terminate_process = false
8
+
5
9
  def self.run(args)
6
10
  raise NotImplementedError
7
11
  end
@@ -13,6 +17,7 @@ module KnapsackPro
13
17
  def initialize(adapter_class)
14
18
  @allocator_builder = KnapsackPro::QueueAllocatorBuilder.new(adapter_class)
15
19
  @allocator = allocator_builder.allocator
20
+ trap_signals
16
21
  end
17
22
 
18
23
  def test_file_paths(args)
@@ -33,6 +38,23 @@ module KnapsackPro
33
38
  def self.child_status
34
39
  $?
35
40
  end
41
+
42
+ def self.handle_signal!
43
+ raise 'Knapsack Pro process was terminated!' if @@terminate_process
44
+ end
45
+
46
+ def self.set_terminate_process
47
+ @@terminate_process = true
48
+ end
49
+
50
+ def trap_signals
51
+ TERMINATION_SIGNALS.each do |signal|
52
+ Signal.trap(signal) {
53
+ puts "#{signal} signal has been received. Terminating Knapsack Pro..."
54
+ @@terminate_process = true
55
+ }
56
+ end
57
+ end
36
58
  end
37
59
  end
38
60
  end
@@ -22,6 +22,7 @@ module KnapsackPro
22
22
  all_test_file_paths: [],
23
23
  }
24
24
  while accumulator[:status] == :next
25
+ handle_signal!
25
26
  accumulator = run_tests(accumulator)
26
27
  end
27
28
 
@@ -29,6 +29,7 @@ module KnapsackPro
29
29
  all_test_file_paths: [],
30
30
  }
31
31
  while accumulator[:status] == :next
32
+ handle_signal!
32
33
  accumulator = run_tests(accumulator)
33
34
  end
34
35
 
@@ -37,6 +37,7 @@ module KnapsackPro
37
37
  all_test_file_paths: [],
38
38
  }
39
39
  while accumulator[:status] == :next
40
+ handle_signal!
40
41
  accumulator = run_tests(accumulator)
41
42
  end
42
43
 
@@ -91,26 +92,44 @@ module KnapsackPro
91
92
  options = ::RSpec::Core::ConfigurationOptions.new(cli_args)
92
93
  rspec_runner = ::RSpec::Core::Runner.new(options)
93
94
 
94
- exit_code = rspec_runner.run($stderr, $stdout)
95
- exitstatus = exit_code if exit_code != 0
96
-
97
- printable_args = args_with_seed_option_added_when_viable(args, rspec_runner)
98
- log_rspec_command(printable_args, test_file_paths, :subset_queue)
99
-
100
- rspec_clear_examples
101
-
102
- KnapsackPro::Hooks::Queue.call_after_subset_queue
103
-
104
- KnapsackPro::Report.save_subset_queue_to_file
105
-
106
- return {
107
- status: :next,
108
- runner: runner,
109
- can_initialize_queue: false,
110
- args: args,
111
- exitstatus: exitstatus,
112
- all_test_file_paths: all_test_file_paths,
113
- }
95
+ begin
96
+ exit_code = rspec_runner.run($stderr, $stdout)
97
+ exitstatus = exit_code if exit_code != 0
98
+ rescue Exception => exception
99
+ KnapsackPro.logger.error("Having exception when running RSpec: #{exception.inspect}")
100
+ KnapsackPro::Formatters::RSpecQueueSummaryFormatter.print_exit_summary
101
+ KnapsackPro::Hooks::Queue.call_after_subset_queue
102
+ KnapsackPro::Hooks::Queue.call_after_queue
103
+ Kernel.exit(1)
104
+ raise
105
+ else
106
+ if rspec_runner.world.wants_to_quit
107
+ KnapsackPro.logger.warn('RSpec wants to quit.')
108
+ set_terminate_process
109
+ end
110
+ if rspec_runner.world.rspec_is_quitting
111
+ KnapsackPro.logger.warn('RSpec is quitting.')
112
+ set_terminate_process
113
+ end
114
+
115
+ printable_args = args_with_seed_option_added_when_viable(args, rspec_runner)
116
+ log_rspec_command(printable_args, test_file_paths, :subset_queue)
117
+
118
+ rspec_clear_examples
119
+
120
+ KnapsackPro::Hooks::Queue.call_after_subset_queue
121
+
122
+ KnapsackPro::Report.save_subset_queue_to_file
123
+
124
+ return {
125
+ status: :next,
126
+ runner: runner,
127
+ can_initialize_queue: false,
128
+ args: args,
129
+ exitstatus: exitstatus,
130
+ all_test_file_paths: all_test_file_paths,
131
+ }
132
+ end
114
133
  end
115
134
  end
116
135
 
@@ -68,6 +68,12 @@ module KnapsackPro
68
68
  @prerun_tests_loaded = true
69
69
  end
70
70
 
71
+ def unexecuted_test_files
72
+ @test_files_with_time.map do |path, hash|
73
+ path unless hash[:measured_time]
74
+ end.compact
75
+ end
76
+
71
77
  def to_a
72
78
  # When the test files are not loaded in the memory then load them from the disk.
73
79
  # Useful for the Regular Mode when the memory is not shared between tracker instances.
@@ -1,3 +1,3 @@
1
1
  module KnapsackPro
2
- VERSION = '5.3.3'
2
+ VERSION = '5.3.5'
3
3
  end
@@ -4,7 +4,13 @@ namespace :knapsack_pro do
4
4
  namespace :queue do
5
5
  task :cucumber, [:cucumber_args] do |_, args|
6
6
  Kernel.system("RAILS_ENV=test RACK_ENV=test #{$PROGRAM_NAME} 'knapsack_pro:queue:cucumber_go[#{args[:cucumber_args]}]'")
7
- Kernel.exit($?.exitstatus)
7
+ exitstatus = $?.exitstatus
8
+ if exitstatus.nil?
9
+ puts 'Something went wrong. Most likely, the process has been killed. Knapsack Pro has been terminated.'
10
+ Kernel.exit(1)
11
+ else
12
+ Kernel.exit(exitstatus)
13
+ end
8
14
  end
9
15
 
10
16
  task :cucumber_go, [:cucumber_args] do |_, args|
@@ -4,7 +4,13 @@ namespace :knapsack_pro do
4
4
  namespace :queue do
5
5
  task :minitest, [:minitest_args] do |_, args|
6
6
  Kernel.system("RAILS_ENV=test RACK_ENV=test #{$PROGRAM_NAME} 'knapsack_pro:queue:minitest_go[#{args[:minitest_args]}]'")
7
- Kernel.exit($?.exitstatus)
7
+ exitstatus = $?.exitstatus
8
+ if exitstatus.nil?
9
+ puts 'Something went wrong. Most likely, the process has been killed. Knapsack Pro has been terminated.'
10
+ Kernel.exit(1)
11
+ else
12
+ Kernel.exit(exitstatus)
13
+ end
8
14
  end
9
15
 
10
16
  task :minitest_go, [:minitest_args] do |_, args|
@@ -4,7 +4,13 @@ namespace :knapsack_pro do
4
4
  namespace :queue do
5
5
  task :rspec, [:rspec_args] do |_, args|
6
6
  Kernel.system("RAILS_ENV=test RACK_ENV=test #{$PROGRAM_NAME} 'knapsack_pro:queue:rspec_go[#{args[:rspec_args]}]'")
7
- Kernel.exit($?.exitstatus)
7
+ exitstatus = $?.exitstatus
8
+ if exitstatus.nil?
9
+ puts 'Something went wrong. Most likely, the process has been killed. Knapsack Pro has been terminated.'
10
+ Kernel.exit(1)
11
+ else
12
+ Kernel.exit(exitstatus)
13
+ end
8
14
  end
9
15
 
10
16
  task :rspec_go, [:rspec_args] do |_, args|
@@ -41,6 +41,7 @@ describe KnapsackPro::Runners::Queue::CucumberRunner do
41
41
  exitstatus: 0,
42
42
  all_test_file_paths: [],
43
43
  }
44
+ expect(described_class).to receive(:handle_signal!)
44
45
  expect(described_class).to receive(:run_tests).with(accumulator).and_return(expected_accumulator)
45
46
 
46
47
  expect(Kernel).to receive(:exit).with(expected_exitstatus)
@@ -66,6 +67,7 @@ describe KnapsackPro::Runners::Queue::CucumberRunner do
66
67
  exitstatus: 0,
67
68
  all_test_file_paths: [],
68
69
  }
70
+ expect(described_class).to receive(:handle_signal!)
69
71
  expect(described_class).to receive(:run_tests).with(accumulator).and_return(expected_accumulator)
70
72
 
71
73
  expect(Kernel).to receive(:exit).with(expected_exitstatus)
@@ -43,6 +43,7 @@ describe KnapsackPro::Runners::Queue::MinitestRunner do
43
43
  exitstatus: 0,
44
44
  all_test_file_paths: [],
45
45
  }
46
+ expect(described_class).to receive(:handle_signal!)
46
47
  expect(described_class).to receive(:run_tests).with(accumulator).and_return(expected_accumulator)
47
48
 
48
49
  expect(Kernel).to receive(:exit).with(expected_exitstatus)
@@ -68,6 +69,7 @@ describe KnapsackPro::Runners::Queue::MinitestRunner do
68
69
  exitstatus: 0,
69
70
  all_test_file_paths: [],
70
71
  }
72
+ expect(described_class).to receive(:handle_signal!)
71
73
  expect(described_class).to receive(:run_tests).with(accumulator).and_return(expected_accumulator)
72
74
 
73
75
  expect(Kernel).to receive(:exit).with(expected_exitstatus)
@@ -49,6 +49,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
49
49
  exitstatus: 0,
50
50
  all_test_file_paths: [],
51
51
  }
52
+ expect(described_class).to receive(:handle_signal!)
52
53
  expect(described_class).to receive(:run_tests).with(accumulator).and_return(expected_accumulator)
53
54
 
54
55
  expect(Kernel).to receive(:exit).with(expected_exitstatus)
@@ -74,6 +75,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
74
75
  exitstatus: 0,
75
76
  all_test_file_paths: [],
76
77
  }
78
+ expect(described_class).to receive(:handle_signal!)
77
79
  expect(described_class).to receive(:run_tests).with(accumulator).and_return(expected_accumulator)
78
80
 
79
81
  expect(Kernel).to receive(:exit).with(expected_exitstatus)
@@ -99,6 +101,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
99
101
  exitstatus: 0,
100
102
  all_test_file_paths: [],
101
103
  }
104
+ expect(described_class).to receive(:handle_signal!)
102
105
  expect(described_class).to receive(:run_tests).with(accumulator).and_return(expected_accumulator)
103
106
 
104
107
  expect(Kernel).to receive(:exit).with(expected_exitstatus)
@@ -124,6 +127,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
124
127
  exitstatus: 0,
125
128
  all_test_file_paths: [],
126
129
  }
130
+ expect(described_class).to receive(:handle_signal!)
127
131
  expect(described_class).to receive(:run_tests).with(accumulator).and_return(expected_accumulator)
128
132
 
129
133
  expect(Kernel).to receive(:exit).with(expected_exitstatus)
@@ -165,6 +169,7 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
165
169
  exitstatus: 0,
166
170
  all_test_file_paths: [],
167
171
  }
172
+ expect(described_class).to receive(:handle_signal!)
168
173
  expect(described_class).to receive(:run_tests).with(accumulator).and_return(expected_accumulator)
169
174
 
170
175
  expect(Kernel).to receive(:exit).with(expected_exitstatus)
@@ -200,76 +205,190 @@ describe KnapsackPro::Runners::Queue::RSpecRunner do
200
205
  let(:test_file_paths) { ['a_spec.rb', 'b_spec.rb'] }
201
206
  let(:logger) { double }
202
207
  let(:rspec_seed) { 7771 }
208
+ let(:exit_code) { [0, 1].sample }
209
+ let(:rspec_wants_to_quit) { false }
210
+ let(:rspec_is_quitting) { false }
211
+ let(:rspec_core_runner) do
212
+ double(world: double(wants_to_quit: rspec_wants_to_quit, rspec_is_quitting: rspec_is_quitting))
213
+ end
203
214
 
204
- before do
205
- subset_queue_id = 'fake-subset-queue-id'
206
- expect(KnapsackPro::Config::EnvGenerator).to receive(:set_subset_queue_id).and_return(subset_queue_id)
215
+ context 'having no exception when running RSpec' do
216
+ before do
217
+ subset_queue_id = 'fake-subset-queue-id'
218
+ expect(KnapsackPro::Config::EnvGenerator).to receive(:set_subset_queue_id).and_return(subset_queue_id)
207
219
 
208
- expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_SUBSET_QUEUE_ID', subset_queue_id)
220
+ expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_SUBSET_QUEUE_ID', subset_queue_id)
209
221
 
210
- tracker = instance_double(KnapsackPro::Tracker)
211
- expect(KnapsackPro).to receive(:tracker).twice.and_return(tracker)
212
- expect(tracker).to receive(:reset!)
213
- expect(tracker).to receive(:set_prerun_tests).with(test_file_paths)
222
+ tracker = instance_double(KnapsackPro::Tracker)
223
+ expect(KnapsackPro).to receive(:tracker).twice.and_return(tracker)
224
+ expect(tracker).to receive(:reset!)
225
+ expect(tracker).to receive(:set_prerun_tests).with(test_file_paths)
214
226
 
215
- expect(described_class).to receive(:ensure_spec_opts_have_rspec_queue_summary_formatter)
216
- options = double
217
- expect(RSpec::Core::ConfigurationOptions).to receive(:new).with([
218
- '--no-color',
219
- '--default-path', 'fake-test-dir',
220
- 'a_spec.rb', 'b_spec.rb',
221
- ]).and_return(options)
227
+ expect(described_class).to receive(:ensure_spec_opts_have_rspec_queue_summary_formatter)
228
+ options = double
229
+ expect(RSpec::Core::ConfigurationOptions).to receive(:new).with([
230
+ '--no-color',
231
+ '--default-path', 'fake-test-dir',
232
+ 'a_spec.rb', 'b_spec.rb',
233
+ ]).and_return(options)
222
234
 
223
- rspec_core_runner = double
224
- expect(RSpec::Core::Runner).to receive(:new).with(options).and_return(rspec_core_runner)
225
- expect(rspec_core_runner).to receive(:run).with($stderr, $stdout).and_return(exit_code)
235
+ expect(RSpec::Core::Runner).to receive(:new).with(options).and_return(rspec_core_runner)
236
+ expect(rspec_core_runner).to receive(:run).with($stderr, $stdout).and_return(exit_code)
226
237
 
227
- expect(described_class).to receive(:rspec_clear_examples)
238
+ expect(described_class).to receive(:rspec_clear_examples)
228
239
 
229
- expect(KnapsackPro::Hooks::Queue).to receive(:call_before_subset_queue)
240
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_before_subset_queue)
230
241
 
231
- expect(KnapsackPro::Hooks::Queue).to receive(:call_after_subset_queue)
242
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_after_subset_queue)
232
243
 
233
- expect(KnapsackPro::Report).to receive(:save_subset_queue_to_file)
244
+ expect(KnapsackPro::Report).to receive(:save_subset_queue_to_file)
234
245
 
235
- configuration = double
236
- expect(rspec_core_runner).to receive(:configuration).twice.and_return(configuration)
237
- expect(configuration).to receive(:seed_used?).and_return(true)
238
- expect(configuration).to receive(:seed).and_return(rspec_seed)
246
+ configuration = double
247
+ expect(rspec_core_runner).to receive(:configuration).twice.and_return(configuration)
248
+ expect(configuration).to receive(:seed_used?).and_return(true)
249
+ expect(configuration).to receive(:seed).and_return(rspec_seed)
239
250
 
240
- expect(KnapsackPro).to receive(:logger).twice.and_return(logger)
241
- expect(logger).to receive(:info)
242
- .with("To retry the last batch of tests fetched from the API Queue, please run the following command on your machine:")
243
- expect(logger).to receive(:info).with(/#{args.join(' ')} --seed #{rspec_seed}/)
244
- end
251
+ expect(KnapsackPro).to receive(:logger).at_least(2).and_return(logger)
252
+ expect(logger).to receive(:info)
253
+ .with("To retry the last batch of tests fetched from the API Queue, please run the following command on your machine:")
254
+ expect(logger).to receive(:info).with(/#{args.join(' ')} --seed #{rspec_seed}/)
255
+ end
245
256
 
246
- context 'when exit code is zero' do
247
- let(:exit_code) { 0 }
257
+ context 'when the exit code is zero' do
258
+ let(:exit_code) { 0 }
248
259
 
249
- it do
250
- expect(subject).to eq({
251
- status: :next,
252
- runner: runner,
253
- can_initialize_queue: false,
254
- args: args,
255
- exitstatus: exitstatus,
256
- all_test_file_paths: test_file_paths,
257
- })
260
+ it do
261
+ expect(subject).to eq({
262
+ status: :next,
263
+ runner: runner,
264
+ can_initialize_queue: false,
265
+ args: args,
266
+ exitstatus: exitstatus,
267
+ all_test_file_paths: test_file_paths,
268
+ })
269
+ end
270
+ end
271
+
272
+ context 'when the exit code is not zero' do
273
+ let(:exit_code) { double }
274
+
275
+ it do
276
+ expect(subject).to eq({
277
+ status: :next,
278
+ runner: runner,
279
+ can_initialize_queue: false,
280
+ args: args,
281
+ exitstatus: exit_code,
282
+ all_test_file_paths: test_file_paths,
283
+ })
284
+ end
285
+ end
286
+
287
+ context 'when RSpec wants to quit' do
288
+ let(:exit_code) { 0 }
289
+ let(:rspec_wants_to_quit) { true }
290
+
291
+ after do
292
+ described_class.class_variable_set(:@@terminate_process, false)
293
+ end
294
+
295
+ it 'terminates the process' do
296
+ expect(logger).to receive(:warn).with('RSpec wants to quit.')
297
+
298
+ expect(described_class.class_variable_get(:@@terminate_process)).to be false
299
+
300
+ expect(subject).to eq({
301
+ status: :next,
302
+ runner: runner,
303
+ can_initialize_queue: false,
304
+ args: args,
305
+ exitstatus: exitstatus,
306
+ all_test_file_paths: test_file_paths,
307
+ })
308
+
309
+ expect(described_class.class_variable_get(:@@terminate_process)).to be true
310
+ end
311
+ end
312
+
313
+ context 'when RSpec is quitting' do
314
+ let(:exit_code) { 0 }
315
+ let(:rspec_is_quitting) { true }
316
+
317
+ after do
318
+ described_class.class_variable_set(:@@terminate_process, false)
319
+ end
320
+
321
+ it 'terminates the process' do
322
+ expect(logger).to receive(:warn).with('RSpec is quitting.')
323
+
324
+ expect(described_class.class_variable_get(:@@terminate_process)).to be false
325
+
326
+ expect(subject).to eq({
327
+ status: :next,
328
+ runner: runner,
329
+ can_initialize_queue: false,
330
+ args: args,
331
+ exitstatus: exitstatus,
332
+ all_test_file_paths: test_file_paths,
333
+ })
334
+
335
+ expect(described_class.class_variable_get(:@@terminate_process)).to be true
336
+ end
258
337
  end
259
338
  end
260
339
 
261
- context 'when exit code is not zero' do
262
- let(:exit_code) { double }
340
+ context 'having exception when running RSpec' do
341
+ before do
342
+ subset_queue_id = 'fake-subset-queue-id'
343
+ expect(KnapsackPro::Config::EnvGenerator).to receive(:set_subset_queue_id).and_return(subset_queue_id)
344
+
345
+ expect(ENV).to receive(:[]=).with('KNAPSACK_PRO_SUBSET_QUEUE_ID', subset_queue_id)
346
+
347
+ tracker = instance_double(KnapsackPro::Tracker)
348
+ expect(KnapsackPro).to receive(:tracker).twice.and_return(tracker)
349
+ expect(tracker).to receive(:reset!)
350
+ expect(tracker).to receive(:set_prerun_tests).with(test_file_paths)
351
+
352
+ expect(described_class).to receive(:ensure_spec_opts_have_rspec_queue_summary_formatter)
353
+ options = double
354
+ expect(RSpec::Core::ConfigurationOptions).to receive(:new).with([
355
+ '--no-color',
356
+ '--default-path', 'fake-test-dir',
357
+ 'a_spec.rb', 'b_spec.rb',
358
+ ]).and_return(options)
359
+
360
+ rspec_core_runner = double
361
+ expect(RSpec::Core::Runner).to receive(:new).with(options).and_return(rspec_core_runner)
362
+ expect(rspec_core_runner).to receive(:run).with($stderr, $stdout).and_raise SystemExit
363
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_before_subset_queue)
364
+ allow(KnapsackPro::Report).to receive(:save_subset_queue_to_file)
365
+ allow(KnapsackPro::Hooks::Queue).to receive(:call_after_subset_queue)
366
+ allow(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
367
+ allow(KnapsackPro::Formatters::RSpecQueueSummaryFormatter).to receive(:print_exit_summary)
368
+ expect(Kernel).to receive(:exit).with(1)
369
+ end
263
370
 
264
- it do
265
- expect(subject).to eq({
266
- status: :next,
267
- runner: runner,
268
- can_initialize_queue: false,
269
- args: args,
270
- exitstatus: exit_code,
271
- all_test_file_paths: test_file_paths,
272
- })
371
+ it 'does not call #save_subset_queue_to_file or #rspec_clear_examples' do
372
+ expect(described_class).not_to receive(:rspec_clear_examples)
373
+ expect(KnapsackPro::Report).not_to receive(:save_subset_queue_to_file)
374
+ expect { subject }.to raise_error SystemExit
375
+ end
376
+
377
+ it 'logs the exception' do
378
+ expect(KnapsackPro).to receive(:logger).once.and_return(logger)
379
+ expect(logger).to receive(:error).with("Having exception when running RSpec: #<SystemExit: SystemExit>")
380
+ expect { subject }.to raise_error SystemExit
381
+ end
382
+
383
+ it 'calls #print_exit_summary' do
384
+ expect(KnapsackPro::Formatters::RSpecQueueSummaryFormatter).to receive(:print_exit_summary)
385
+ expect { subject }.to raise_error SystemExit
386
+ end
387
+
388
+ it 'calls #call_after_subset_queue and #call_after_queue' do
389
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_after_subset_queue)
390
+ expect(KnapsackPro::Hooks::Queue).to receive(:call_after_queue)
391
+ expect { subject }.to raise_error SystemExit
273
392
  end
274
393
  end
275
394
  end
@@ -185,4 +185,21 @@ describe KnapsackPro::Tracker do
185
185
  expect(tracker.prerun_tests_loaded).to be false
186
186
  end
187
187
  end
188
+
189
+
190
+ describe '#unexecuted_test_files' do
191
+ before do
192
+ tracker.set_prerun_tests(['a_spec.rb', 'b_spec.rb', 'c_spec.rb'])
193
+
194
+ # measure execution time for b_spec.rb
195
+ tracker.current_test_path = 'b_spec.rb'
196
+ tracker.start_timer
197
+ sleep 0.1
198
+ tracker.stop_timer
199
+ end
200
+
201
+ it 'returns test files without measured time' do
202
+ expect(tracker.unexecuted_test_files).to eq(['a_spec.rb', 'c_spec.rb'])
203
+ end
204
+ end
188
205
  end
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: 5.3.3
4
+ version: 5.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - ArturT
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-21 00:00:00.000000000 Z
11
+ date: 2023-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake