Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

Commit 17802c2

Browse files
Track eliminated ids instead of remaining ids
This allows the recursive strategy to minimise the number of examples it runs, as in the doubly-recursive case (i.e. where both LHS and RHS are implicated in the failure) the recursion on the RHS can take advantage of examples eliminated in the recursion on the LHS. This has meant more reliance on object-level state, which I'll attempt to minimise separately.
1 parent 362d7d0 commit 17802c2

File tree

1 file changed

+28
-16
lines changed

1 file changed

+28
-16
lines changed

lib/rspec/core/bisect/example_minimizer.rb

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module Bisect
66
# repeatedly running different subsets of the suite.
77
class ExampleMinimizer
88
attr_reader :runner, :reporter, :all_example_ids, :failed_example_ids
9-
attr_accessor :remaining_ids
9+
attr_accessor :eliminated_ids
1010

1111
def initialize(runner, reporter)
1212
@runner = runner
@@ -16,7 +16,7 @@ def initialize(runner, reporter)
1616
def find_minimal_repro
1717
prep
1818

19-
self.remaining_ids, duration = track_duration do
19+
_, duration = track_duration do
2020
bisect_over(non_failing_example_ids)
2121
end
2222

@@ -28,15 +28,19 @@ def find_minimal_repro
2828
end
2929

3030
def bisect_over(candidate_ids)
31-
return [] if get_expected_failures_for?([])
31+
if get_expected_failures_for?([])
32+
self.eliminated_ids = non_failing_example_ids
33+
return
34+
end
3235

33-
bisect_over_recursive(candidate_ids, [])
36+
bisect_over_recursive(candidate_ids)
3437
end
3538

36-
def bisect_over_recursive(candidate_ids, fixed)
37-
return candidate_ids if candidate_ids.length == 1
39+
def bisect_over_recursive(candidate_ids)
40+
return if candidate_ids.one?
41+
3842
slice_size = (candidate_ids.length / 2.0).ceil
39-
slices = candidate_ids.each_slice(slice_size).to_a
43+
lhs, rhs = candidate_ids.each_slice(slice_size).to_a
4044

4145
notify(
4246
:bisect_round_started,
@@ -45,31 +49,34 @@ def bisect_over_recursive(candidate_ids, fixed)
4549
:remaining_count => candidate_ids.size
4650
)
4751

48-
ids_to_ignore = slices.find do |ids|
49-
get_expected_failures_for?(candidate_ids - ids + fixed)
52+
ids_to_ignore = [lhs, rhs].find do |ids|
53+
get_expected_failures_for?(remaining_ids - ids)
5054
end
5155

5256
if ids_to_ignore
53-
self.remaining_ids = candidate_ids - ids_to_ignore
57+
self.eliminated_ids += ids_to_ignore
5458
notify(
5559
:bisect_ignoring_ids,
5660
:ids_to_ignore => ids_to_ignore,
5761
:remaining_ids => remaining_ids
5862
)
59-
bisect_over_recursive(remaining_ids, fixed)
63+
bisect_over_recursive(candidate_ids - ids_to_ignore)
6064
else
61-
slices.permutation(2).map do |slice, other_slice|
62-
bisect_over_recursive(slice, fixed + other_slice)
63-
end.flatten(1)
65+
bisect_over_recursive(lhs)
66+
bisect_over_recursive(rhs)
6467
end
6568
end
6669

70+
def remaining_ids
71+
non_failing_example_ids - eliminated_ids
72+
end
73+
6774
def currently_needed_ids
6875
remaining_ids + failed_example_ids
6976
end
7077

7178
def repro_command_for_currently_needed_ids
72-
return runner.repro_command_from(currently_needed_ids) if remaining_ids
79+
return runner.repro_command_from(currently_needed_ids) if eliminated_ids
7380
"(Not yet enough information to provide any repro command)"
7481
end
7582

@@ -82,6 +89,7 @@ def prep
8289
original_results = runner.original_results
8390
@all_example_ids = original_results.all_example_ids
8491
@failed_example_ids = original_results.failed_example_ids
92+
@eliminated_ids = []
8593
end
8694

8795
if @failed_example_ids.empty?
@@ -100,7 +108,11 @@ def non_failing_example_ids
100108

101109
def get_expected_failures_for?(ids)
102110
ids_to_run = ids + failed_example_ids
103-
notify(:bisect_individual_run_start, :command => runner.repro_command_from(ids_to_run))
111+
notify(
112+
:bisect_individual_run_start,
113+
:command => runner.repro_command_from(ids_to_run),
114+
:ids_to_run => ids_to_run
115+
)
104116

105117
results, duration = track_duration { runner.run(ids_to_run) }
106118
notify(:bisect_individual_run_complete, :duration => duration, :results => results)

0 commit comments

Comments
 (0)