blob: 77dcc8b70f33cc3dbeb9d1f808208b97db44fb07 [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.devtools.build.lib.buildtool;
16
gregce45ae0962017-07-22 00:11:13 +020017import com.google.common.annotations.VisibleForTesting;
Googler2c19a572015-07-16 08:38:49 +000018import com.google.common.base.MoreObjects;
tomlua155b532017-11-08 20:12:47 +010019import com.google.common.base.Preconditions;
felly2ffb0af2019-11-18 09:12:52 -080020import com.google.common.util.concurrent.Futures;
21import com.google.common.util.concurrent.ListenableFuture;
jcater44c99422020-04-20 15:52:18 -070022import com.google.devtools.build.lib.analysis.AspectValue;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010023import com.google.devtools.build.lib.analysis.ConfiguredTarget;
Ulf Adams59dbf682015-09-17 11:36:43 +000024import com.google.devtools.build.lib.analysis.config.BuildConfigurationCollection;
steinman81668112019-11-08 14:13:07 -080025import com.google.devtools.build.lib.buildeventstream.BuildEvent.LocalFile.LocalFileCompression;
ulfjack8c214fd2019-04-29 05:02:54 -070026import com.google.devtools.build.lib.buildeventstream.BuildEvent.LocalFile.LocalFileType;
ulfjack54c8fcb2018-11-19 05:36:37 -080027import com.google.devtools.build.lib.buildeventstream.BuildToolLogs;
ulfjack8c214fd2019-04-29 05:02:54 -070028import com.google.devtools.build.lib.buildeventstream.BuildToolLogs.LogFileEntry;
mschaller854bb902020-03-03 10:56:14 -080029import com.google.devtools.build.lib.util.DetailedExitCode;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010030import com.google.devtools.build.lib.util.ExitCode;
ulfjack54c8fcb2018-11-19 05:36:37 -080031import com.google.devtools.build.lib.util.Pair;
32import com.google.devtools.build.lib.vfs.Path;
33import com.google.protobuf.ByteString;
34import java.util.ArrayList;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010035import java.util.Collection;
36import java.util.Collections;
ulfjack54c8fcb2018-11-19 05:36:37 -080037import java.util.List;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010038import javax.annotation.Nullable;
39
40/**
41 * Contains information about the result of a build. While BuildRequest is immutable, this class is
42 * mutable.
43 */
44public final class BuildResult {
45 private long startTimeMillis = 0; // milliseconds since UNIX epoch.
46 private long stopTimeMillis = 0;
47
dmaclachba7df7d2019-11-07 07:46:56 -080048 private boolean wasSuspended = false;
49
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010050 private Throwable crash = null;
51 private boolean catastrophe = false;
Florian Weikert63da2e72016-02-25 00:22:05 +000052 private boolean stopOnFirstFailure;
mschaller854bb902020-03-03 10:56:14 -080053 private DetailedExitCode detailedExitCode =
54 DetailedExitCode.justExitCode(ExitCode.BLAZE_INTERNAL_ERROR);
Ulf Adams59dbf682015-09-17 11:36:43 +000055
56 private BuildConfigurationCollection configurations;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010057 private Collection<ConfiguredTarget> actualTargets;
58 private Collection<ConfiguredTarget> testTargets;
59 private Collection<ConfiguredTarget> successfulTargets;
gregce45ae0962017-07-22 00:11:13 +020060 private Collection<ConfiguredTarget> skippedTargets;
tomlu6ed4fd52018-04-03 10:01:10 -070061 private Collection<AspectValue> successfulAspects;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010062
ulfjack54c8fcb2018-11-19 05:36:37 -080063 private final BuildToolLogCollection buildToolLogCollection = new BuildToolLogCollection();
64
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010065 public BuildResult(long startTimeMillis) {
66 this.startTimeMillis = startTimeMillis;
67 }
68
69 /**
70 * Record the time (according to System.currentTimeMillis()) at which the
71 * service of this request was completed.
72 */
73 public void setStopTime(long stopTimeMillis) {
74 this.stopTimeMillis = stopTimeMillis;
75 }
76
77 /**
78 * Return the time (according to System.currentTimeMillis()) at which the
79 * service of this request was completed.
80 */
81 public long getStopTime() {
82 return stopTimeMillis;
83 }
84
85 /**
86 * Returns the elapsed time in seconds for the service of this request. Not
87 * defined for requests that have not been serviced.
88 */
89 public double getElapsedSeconds() {
90 if (startTimeMillis == 0 || stopTimeMillis == 0) {
91 throw new IllegalStateException("BuildRequest has not been serviced");
92 }
93 return (stopTimeMillis - startTimeMillis) / 1000.0;
94 }
95
dmaclachba7df7d2019-11-07 07:46:56 -080096 /** Record if the build was suspended (SIGSTOP or hardware put to sleep). */
97 public void setWasSuspended(boolean wasSuspended) {
98 this.wasSuspended = wasSuspended;
99 }
100
101 /** Whether the build was suspended (SIGSTOP or hardware put to sleep). */
102 public boolean getWasSuspended() {
103 return wasSuspended;
104 }
105
mschaller854bb902020-03-03 10:56:14 -0800106 public void setDetailedExitCode(DetailedExitCode detailedExitCode) {
107 this.detailedExitCode = detailedExitCode;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100108 }
109
mschaller854bb902020-03-03 10:56:14 -0800110 /** True iff the build request has been successfully completed. */
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100111 public boolean getSuccess() {
mschaller854bb902020-03-03 10:56:14 -0800112 return detailedExitCode.isSuccess();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100113 }
114
115 /**
mschaller854bb902020-03-03 10:56:14 -0800116 * Gets the {@link DetailedExitCode} containing the {@link ExitCode} and optional failure detail
117 * to complete the command with.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100118 */
mschaller854bb902020-03-03 10:56:14 -0800119 public DetailedExitCode getDetailedExitCode() {
120 return detailedExitCode;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100121 }
122
123 /**
124 * Sets the RuntimeException / Error that induced a Blaze crash.
125 */
126 public void setUnhandledThrowable(Throwable crash) {
127 Preconditions.checkState(crash == null ||
128 ((crash instanceof RuntimeException) || (crash instanceof Error)));
129 this.crash = crash;
130 }
131
132 /**
133 * Sets a "catastrophe": A build failure severe enough to halt a keep_going build.
134 */
135 public void setCatastrophe() {
136 this.catastrophe = true;
137 }
138
139 /**
140 * Was the build a "catastrophe": A build failure severe enough to halt a keep_going build.
141 */
142 public boolean wasCatastrophe() {
143 return catastrophe;
144 }
145
146 /**
Florian Weikert63da2e72016-02-25 00:22:05 +0000147 * Whether some targets were skipped because of {@code setStopOnFirstFailure}.
148 */
Florian Weikert5aa538e2016-03-11 16:27:13 +0000149 public boolean getStopOnFirstFailure() {
150 return stopOnFirstFailure;
Florian Weikert63da2e72016-02-25 00:22:05 +0000151 }
152
153 /**
154 * Indicates that remaining targets should be skipped once a target breaks/fails.
155 * This will be set when --nokeep_going or --notest_keep_going is set.
156 */
157 public void setStopOnFirstFailure(boolean stopOnFirstFailure) {
158 this.stopOnFirstFailure = stopOnFirstFailure;
159 }
160
161 /**
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100162 * Gets the Blaze crash Throwable. Null if Blaze did not crash.
163 */
164 public Throwable getUnhandledThrowable() {
165 return crash;
166 }
167
Ulf Adams59dbf682015-09-17 11:36:43 +0000168 public void setBuildConfigurationCollection(BuildConfigurationCollection configurations) {
169 this.configurations = configurations;
170 }
171
172 /**
173 * Returns the build configuration collection used for the build.
174 */
175 public BuildConfigurationCollection getBuildConfigurationCollection() {
176 return configurations;
177 }
178
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100179 /**
180 * @see #getActualTargets
181 */
182 public void setActualTargets(Collection<ConfiguredTarget> actualTargets) {
183 this.actualTargets = actualTargets;
184 }
185
186 /**
187 * Returns the actual set of targets which we attempted to build. This value
188 * is set during the build, after the target patterns have been parsed and
189 * resolved. If --keep_going is specified, this set may exclude targets that
190 * could not be found or successfully analyzed. It may be examined after the
191 * build. May be null even after the build, if there were errors in the
192 * loading or analysis phases.
193 */
194 public Collection<ConfiguredTarget> getActualTargets() {
195 return actualTargets;
196 }
197
198 /**
199 * @see #getTestTargets
200 */
201 public void setTestTargets(@Nullable Collection<ConfiguredTarget> testTargets) {
202 this.testTargets = testTargets == null ? null : Collections.unmodifiableCollection(testTargets);
203 }
204
205 /**
206 * Returns the actual unmodifiable collection of targets which we attempted to
207 * test. This value is set at the end of the build analysis phase, after the
208 * test target patterns have been parsed and resolved. If --keep_going is
209 * specified, this collection may exclude targets that could not be found or
210 * successfully analyzed. It may be examined after the build. May be null even
211 * after the build, if there were errors in the loading or analysis phases or
212 * if testing was not requested.
213 */
214 public Collection<ConfiguredTarget> getTestTargets() {
215 return testTargets;
216 }
217
218 /**
219 * @see #getSuccessfulTargets
220 */
221 void setSuccessfulTargets(Collection<ConfiguredTarget> successfulTargets) {
222 this.successfulTargets = successfulTargets;
223 }
224
tomlu6ed4fd52018-04-03 10:01:10 -0700225 /** @see #getSuccessfulAspects */
226 void setSuccessfulAspects(Collection<AspectValue> successfulAspects) {
227 this.successfulAspects = successfulAspects;
228 }
229
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100230 /**
tomlu6ed4fd52018-04-03 10:01:10 -0700231 * Returns the set of targets that were successfully built. This value is set at the end of the
232 * build, after the target patterns have been parsed and resolved and after attempting to build
233 * the targets. If --keep_going is specified, this set may exclude targets that could not be found
234 * or successfully analyzed, or could not be built. It may be examined after the build. May be
235 * null if the execution phase was not attempted, as may happen if there are errors in the loading
236 * phase, for example.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100237 */
238 public Collection<ConfiguredTarget> getSuccessfulTargets() {
239 return successfulTargets;
240 }
241
gregce45ae0962017-07-22 00:11:13 +0200242 /**
tomlu6ed4fd52018-04-03 10:01:10 -0700243 * Returns the set of aspects that were successfully built. This value is set at the end of the
244 * build, after the target patterns have been parsed and resolved and after attempting to build
245 * the targets. If --keep_going is specified, this set may exclude targets that could not be found
246 * or successfully analyzed, or could not be built. It may be examined after the build. May be
247 * null if the execution phase was not attempted, as may happen if there are errors in the loading
248 * phase, for example.
249 */
250 public Collection<AspectValue> getSuccessfulAspects() {
251 return successfulAspects;
252 }
253
254 /**
gregce45ae0962017-07-22 00:11:13 +0200255 * See {@link #getSkippedTargets()}.
256 */
257 void setSkippedTargets(Collection<ConfiguredTarget> skippedTargets) {
258 this.skippedTargets = skippedTargets;
259 }
260
261 /**
262 * Returns the set of targets which were skipped (Blaze didn't attempt to execute them)
263 * because they're not compatible with the build's target platform.
264 */
265 @VisibleForTesting
266 public Collection<ConfiguredTarget> getSkippedTargets() {
267 return skippedTargets;
268 }
269
ulfjack54c8fcb2018-11-19 05:36:37 -0800270 /**
271 * Collection of data for the build tool logs event. This may only be modified until the
272 * BuildCompleteEvent is posted; any changes after that event is handled will not be included in
273 * the build tool logs event.
274 */
275 public BuildToolLogCollection getBuildToolLogCollection() {
276 return buildToolLogCollection;
277 }
278
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100279 /** For debugging. */
280 @Override
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100281 public String toString() {
Googler2c19a572015-07-16 08:38:49 +0000282 return MoreObjects.toStringHelper(this)
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100283 .add("startTimeMillis", startTimeMillis)
284 .add("stopTimeMillis", stopTimeMillis)
285 .add("crash", crash)
286 .add("catastrophe", catastrophe)
mschaller854bb902020-03-03 10:56:14 -0800287 .add("detailedExitCode", detailedExitCode)
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100288 .add("actualTargets", actualTargets)
289 .add("testTargets", testTargets)
290 .add("successfulTargets", successfulTargets)
ulfjack54c8fcb2018-11-19 05:36:37 -0800291 .add("buildToolLogCollection", buildToolLogCollection)
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100292 .toString();
293 }
ulfjack54c8fcb2018-11-19 05:36:37 -0800294
ulfjack8d37e0b2018-11-20 03:10:13 -0800295 /**
296 * Collection of data for the build tool logs event. See {@link BuildToolLogs} for details.
297 */
ulfjack54c8fcb2018-11-19 05:36:37 -0800298 public static final class BuildToolLogCollection {
299 private final List<Pair<String, ByteString>> directValues = new ArrayList<>();
felly2ffb0af2019-11-18 09:12:52 -0800300 private final List<Pair<String, ListenableFuture<String>>> futureUris = new ArrayList<>();
ulfjack8c214fd2019-04-29 05:02:54 -0700301 private final List<LogFileEntry> localFiles = new ArrayList<>();
ulfjack54c8fcb2018-11-19 05:36:37 -0800302 private boolean frozen;
303
304 public BuildToolLogCollection freeze() {
305 frozen = true;
306 return this;
307 }
308
ulfjackb2cb6402019-01-24 04:04:48 -0800309 @VisibleForTesting
ulfjack8c214fd2019-04-29 05:02:54 -0700310 public List<LogFileEntry> getLocalFiles() {
ulfjackb2cb6402019-01-24 04:04:48 -0800311 return localFiles;
312 }
313
ulfjack54c8fcb2018-11-19 05:36:37 -0800314 public BuildToolLogCollection addDirectValue(String name, byte[] data) {
315 Preconditions.checkState(!frozen);
316 this.directValues.add(Pair.of(name, ByteString.copyFrom(data)));
317 return this;
318 }
319
320 public BuildToolLogCollection addUri(String name, String uri) {
321 Preconditions.checkState(!frozen);
felly2ffb0af2019-11-18 09:12:52 -0800322 this.futureUris.add(Pair.of(name, Futures.immediateFuture(uri)));
323 return this;
324 }
325
326 public BuildToolLogCollection addUriFuture(String name, ListenableFuture<String> uriFuture) {
327 Preconditions.checkState(!frozen);
328 this.futureUris.add(Pair.of(name, uriFuture));
ulfjack54c8fcb2018-11-19 05:36:37 -0800329 return this;
330 }
331
332 public BuildToolLogCollection addLocalFile(String name, Path path) {
steinman81668112019-11-08 14:13:07 -0800333 return addLocalFile(name, path, LocalFileType.LOG, LocalFileCompression.NONE);
ulfjack8c214fd2019-04-29 05:02:54 -0700334 }
335
336 public BuildToolLogCollection addLocalFile(
steinman81668112019-11-08 14:13:07 -0800337 String name, Path path, LocalFileType localFileType, LocalFileCompression compression) {
ulfjack54c8fcb2018-11-19 05:36:37 -0800338 Preconditions.checkState(!frozen);
steinman48957db2019-11-26 09:42:36 -0800339 switch (compression) {
340 case GZIP:
341 name = name + ".gz";
342 break;
343 case NONE:
344 break;
345 }
steinman81668112019-11-08 14:13:07 -0800346 this.localFiles.add(new LogFileEntry(name, path, localFileType, compression));
ulfjack54c8fcb2018-11-19 05:36:37 -0800347 return this;
348 }
349
350 public BuildToolLogs toEvent() {
351 Preconditions.checkState(frozen);
felly2ffb0af2019-11-18 09:12:52 -0800352 return new BuildToolLogs(directValues, futureUris, localFiles);
ulfjack54c8fcb2018-11-19 05:36:37 -0800353 }
354
355 /** For debugging. */
356 @Override
357 public String toString() {
358 return MoreObjects.toStringHelper(this)
359 .add("directValues", directValues)
felly2ffb0af2019-11-18 09:12:52 -0800360 .add("futureUris", futureUris)
ulfjackb2cb6402019-01-24 04:04:48 -0800361 .add("localFiles", localFiles)
ulfjack54c8fcb2018-11-19 05:36:37 -0800362 .toString();
363 }
364 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100365}