34
34
import com .google .devtools .build .lib .concurrent .ThreadSafety ;
35
35
import com .google .devtools .build .lib .skyframe .AspectKeyCreator .AspectKey ;
36
36
import com .google .devtools .build .lib .skyframe .ConfiguredTargetKey ;
37
+ import com .google .devtools .build .lib .skyframe .TopLevelStatusEvents .TopLevelTargetPendingExecutionEvent ;
37
38
import com .google .devtools .build .lib .view .test .TestStatus .BlazeTestStatus ;
39
+ import com .google .errorprone .annotations .CanIgnoreReturnValue ;
38
40
import com .google .errorprone .annotations .concurrent .GuardedBy ;
39
41
import java .util .Collection ;
40
42
import java .util .concurrent .ConcurrentHashMap ;
@@ -79,8 +81,6 @@ public void buildStarting(BuildStartingEvent event) {
79
81
*/
80
82
@ Subscribe
81
83
public void populateTargets (TestFilteringCompleteEvent event ) {
82
- int expectedCompletions = aspectCount .get () + 1 ; // + 1 for target itself
83
- checkState (expectedCompletions > 0 , "Haven't received BuildStartingEvent" );
84
84
ImmutableSet <ConfiguredTarget > testTargets =
85
85
event .getTestTargets () != null
86
86
? ImmutableSet .copyOf (event .getTestTargets ())
@@ -92,16 +92,48 @@ public void populateTargets(TestFilteringCompleteEvent event) {
92
92
// we'll still get (and ignore) a TestSummary event, but that event isn't published to BEP.
93
93
continue ;
94
94
}
95
- // We want target summaries for alias targets, but note they don't receive test summaries.
96
- TargetSummaryAggregator aggregator =
97
- new TargetSummaryAggregator (
98
- target ,
99
- expectedCompletions ,
100
- !AliasProvider .isAlias (target ) && testTargets .contains (target ));
101
- TargetSummaryAggregator oldAggregator = aggregators .put (asKey (target ), aggregator );
95
+ TargetSummaryAggregator oldAggregator =
96
+ replaceAggregatorForTarget (/*isTest=*/ testTargets .contains (target ), target );
102
97
checkState (
103
- oldAggregator == null , "target: %s, values: %s %s" , target , oldAggregator , aggregator );
98
+ oldAggregator == null ,
99
+ "target: %s, values: %s %s" ,
100
+ target ,
101
+ oldAggregator ,
102
+ aggregators .get (asKey (target )));
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Populates the aggregator for a particular top level target, including test targets.
108
+ *
109
+ * <p>Since the event is fired from within a SkyFunction, it is possible to receive duplicate
110
+ * events. In case of duplication, simply return without creating any new aggregator.
111
+ */
112
+ @ Subscribe
113
+ @ AllowConcurrentEvents
114
+ public void populateTarget (TopLevelTargetPendingExecutionEvent event ) {
115
+ replaceAggregatorForTarget (event .isTest (), event .configuredTarget ());
116
+ }
117
+
118
+ /**
119
+ * Creates a TargetSummaryAggregator for the given target and stores it in {@link aggregators}
120
+ *
121
+ * @return the existing aggregator, if any.
122
+ */
123
+ @ Nullable
124
+ @ CanIgnoreReturnValue
125
+ private TargetSummaryAggregator replaceAggregatorForTarget (
126
+ boolean isTest , ConfiguredTarget target ) {
127
+ if (aggregators .containsKey (asKey (target ))) {
128
+ return null ;
104
129
}
130
+ int expectedCompletions = aspectCount .get () + 1 ; // + 1 for target itself
131
+ checkState (expectedCompletions > 0 , "Haven't received BuildStartingEvent" );
132
+ // We want target summaries for alias targets, but note they don't receive test summaries.
133
+ TargetSummaryAggregator aggregator =
134
+ new TargetSummaryAggregator (
135
+ target , expectedCompletions , isTest && !AliasProvider .isAlias (target ));
136
+ return aggregators .put (asKey (target ), aggregator );
105
137
}
106
138
107
139
@ Subscribe
0 commit comments