knapsack_pro 5.3.3 → 5.3.5

Sign up to get free protection for your applications and to get access to all the features.
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