@@ -6,7 +6,7 @@ module Bisect
6
6
# repeatedly running different subsets of the suite.
7
7
class ExampleMinimizer
8
8
attr_reader :runner , :reporter , :all_example_ids , :failed_example_ids
9
- attr_accessor :remaining_ids
9
+ attr_accessor :eliminated_ids
10
10
11
11
def initialize ( runner , reporter )
12
12
@runner = runner
@@ -16,7 +16,7 @@ def initialize(runner, reporter)
16
16
def find_minimal_repro
17
17
prep
18
18
19
- self . remaining_ids , duration = track_duration do
19
+ _ , duration = track_duration do
20
20
bisect_over ( non_failing_example_ids )
21
21
end
22
22
@@ -28,15 +28,19 @@ def find_minimal_repro
28
28
end
29
29
30
30
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
32
35
33
- bisect_over_recursive ( candidate_ids , [ ] )
36
+ bisect_over_recursive ( candidate_ids )
34
37
end
35
38
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
+
38
42
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
40
44
41
45
notify (
42
46
:bisect_round_started ,
@@ -45,31 +49,34 @@ def bisect_over_recursive(candidate_ids, fixed)
45
49
:remaining_count => candidate_ids . size
46
50
)
47
51
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 )
50
54
end
51
55
52
56
if ids_to_ignore
53
- self . remaining_ids = candidate_ids - ids_to_ignore
57
+ self . eliminated_ids += ids_to_ignore
54
58
notify (
55
59
:bisect_ignoring_ids ,
56
60
:ids_to_ignore => ids_to_ignore ,
57
61
:remaining_ids => remaining_ids
58
62
)
59
- bisect_over_recursive ( remaining_ids , fixed )
63
+ bisect_over_recursive ( candidate_ids - ids_to_ignore )
60
64
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 )
64
67
end
65
68
end
66
69
70
+ def remaining_ids
71
+ non_failing_example_ids - eliminated_ids
72
+ end
73
+
67
74
def currently_needed_ids
68
75
remaining_ids + failed_example_ids
69
76
end
70
77
71
78
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
73
80
"(Not yet enough information to provide any repro command)"
74
81
end
75
82
@@ -82,6 +89,7 @@ def prep
82
89
original_results = runner . original_results
83
90
@all_example_ids = original_results . all_example_ids
84
91
@failed_example_ids = original_results . failed_example_ids
92
+ @eliminated_ids = [ ]
85
93
end
86
94
87
95
if @failed_example_ids . empty?
@@ -100,7 +108,11 @@ def non_failing_example_ids
100
108
101
109
def get_expected_failures_for? ( ids )
102
110
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
+ )
104
116
105
117
results , duration = track_duration { runner . run ( ids_to_run ) }
106
118
notify ( :bisect_individual_run_complete , :duration => duration , :results => results )
0 commit comments