Damien Martin-Guillerez | f88f4d8 | 2015-09-25 13:56:55 +0000 | [diff] [blame] | 1 | // Copyright 2014 The Bazel Authors. All rights reserved. |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 2 | // |
| 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 | |
| 15 | package com.google.devtools.build.lib.analysis; |
| 16 | |
Klaus Aehlig | 8a8a7fc | 2016-10-26 14:27:48 +0000 | [diff] [blame] | 17 | import com.google.common.collect.ImmutableList; |
Klaus Aehlig | 4901d8b | 2017-04-10 15:13:59 +0000 | [diff] [blame^] | 18 | import com.google.common.collect.ImmutableSet; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 19 | import com.google.common.collect.Iterables; |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 20 | import com.google.devtools.build.lib.actions.Artifact; |
Klaus Aehlig | 4901d8b | 2017-04-10 15:13:59 +0000 | [diff] [blame^] | 21 | import com.google.devtools.build.lib.actions.EventReportingArtifacts; |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 22 | import com.google.devtools.build.lib.analysis.TopLevelArtifactHelper.ArtifactsInOutputGroup; |
Klaus Aehlig | 4901d8b | 2017-04-10 15:13:59 +0000 | [diff] [blame^] | 23 | import com.google.devtools.build.lib.buildeventstream.ArtifactGroupNamer; |
aehlig | 617bb89 | 2017-04-04 15:03:23 +0000 | [diff] [blame] | 24 | import com.google.devtools.build.lib.buildeventstream.BuildEventConverters; |
Klaus Aehlig | 8a8a7fc | 2016-10-26 14:27:48 +0000 | [diff] [blame] | 25 | import com.google.devtools.build.lib.buildeventstream.BuildEventId; |
| 26 | import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos; |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 27 | import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.OutputGroup; |
Klaus Aehlig | 74d716b | 2016-11-23 12:38:24 +0000 | [diff] [blame] | 28 | import com.google.devtools.build.lib.buildeventstream.BuildEventWithOrderConstraint; |
Klaus Aehlig | 8a8a7fc | 2016-10-26 14:27:48 +0000 | [diff] [blame] | 29 | import com.google.devtools.build.lib.buildeventstream.GenericBuildEvent; |
Klaus Aehlig | d1f4a16 | 2016-10-25 14:51:55 +0000 | [diff] [blame] | 30 | import com.google.devtools.build.lib.causes.Cause; |
Klaus Aehlig | 1f452c3 | 2017-02-02 10:19:15 +0000 | [diff] [blame] | 31 | import com.google.devtools.build.lib.cmdline.Label; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 32 | import com.google.devtools.build.lib.collect.nestedset.NestedSet; |
| 33 | import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; |
Klaus Aehlig | 4901d8b | 2017-04-10 15:13:59 +0000 | [diff] [blame^] | 34 | import com.google.devtools.build.lib.collect.nestedset.NestedSetView; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 35 | import com.google.devtools.build.lib.collect.nestedset.Order; |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 36 | import com.google.devtools.build.lib.packages.AttributeMap; |
Klaus Aehlig | 1f452c3 | 2017-02-02 10:19:15 +0000 | [diff] [blame] | 37 | import com.google.devtools.build.lib.rules.test.TestProvider; |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 38 | import com.google.devtools.build.lib.syntax.Type; |
Mark Schaller | 6df8179 | 2015-12-10 18:47:47 +0000 | [diff] [blame] | 39 | import com.google.devtools.build.lib.util.Preconditions; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 40 | import com.google.devtools.build.skyframe.SkyValue; |
Klaus Aehlig | 8a8a7fc | 2016-10-26 14:27:48 +0000 | [diff] [blame] | 41 | import java.util.Collection; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 42 | |
Klaus Aehlig | 8a8a7fc | 2016-10-26 14:27:48 +0000 | [diff] [blame] | 43 | /** This event is fired as soon as a target is either built or fails. */ |
Klaus Aehlig | 4901d8b | 2017-04-10 15:13:59 +0000 | [diff] [blame^] | 44 | public final class TargetCompleteEvent |
| 45 | implements SkyValue, BuildEventWithOrderConstraint, EventReportingArtifacts { |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 46 | |
| 47 | private final ConfiguredTarget target; |
Klaus Aehlig | d1f4a16 | 2016-10-25 14:51:55 +0000 | [diff] [blame] | 48 | private final NestedSet<Cause> rootCauses; |
Klaus Aehlig | 74d716b | 2016-11-23 12:38:24 +0000 | [diff] [blame] | 49 | private final Collection<BuildEventId> postedAfter; |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 50 | private final Iterable<ArtifactsInOutputGroup> outputs; |
Klaus Aehlig | 6f97850 | 2016-11-30 12:12:56 +0000 | [diff] [blame] | 51 | private final boolean isTest; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 52 | |
Klaus Aehlig | 6f97850 | 2016-11-30 12:12:56 +0000 | [diff] [blame] | 53 | private TargetCompleteEvent( |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 54 | ConfiguredTarget target, |
| 55 | NestedSet<Cause> rootCauses, |
| 56 | Iterable<ArtifactsInOutputGroup> outputs, |
| 57 | boolean isTest) { |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 58 | this.target = target; |
Klaus Aehlig | d1f4a16 | 2016-10-25 14:51:55 +0000 | [diff] [blame] | 59 | this.rootCauses = |
| 60 | (rootCauses == null) ? NestedSetBuilder.<Cause>emptySet(Order.STABLE_ORDER) : rootCauses; |
Klaus Aehlig | 74d716b | 2016-11-23 12:38:24 +0000 | [diff] [blame] | 61 | |
| 62 | ImmutableList.Builder postedAfterBuilder = ImmutableList.builder(); |
| 63 | for (Cause cause : getRootCauses()) { |
| 64 | postedAfterBuilder.add(BuildEventId.fromCause(cause)); |
| 65 | } |
| 66 | this.postedAfter = postedAfterBuilder.build(); |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 67 | this.outputs = outputs; |
Klaus Aehlig | 6f97850 | 2016-11-30 12:12:56 +0000 | [diff] [blame] | 68 | this.isTest = isTest; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 69 | } |
| 70 | |
Klaus Aehlig | 6f97850 | 2016-11-30 12:12:56 +0000 | [diff] [blame] | 71 | /** Construct a successful target completion event. */ |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 72 | public static TargetCompleteEvent createSuccessfulTarget( |
| 73 | ConfiguredTarget ct, NestedSet<ArtifactsInOutputGroup> outputs) { |
| 74 | return new TargetCompleteEvent(ct, null, outputs, false); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 75 | } |
| 76 | |
Klaus Aehlig | 6f97850 | 2016-11-30 12:12:56 +0000 | [diff] [blame] | 77 | /** Construct a successful target completion event for a target that will be tested. */ |
| 78 | public static TargetCompleteEvent createSuccessfulTestTarget(ConfiguredTarget ct) { |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 79 | return new TargetCompleteEvent(ct, null, ImmutableList.<ArtifactsInOutputGroup>of(), true); |
Klaus Aehlig | 6f97850 | 2016-11-30 12:12:56 +0000 | [diff] [blame] | 80 | } |
| 81 | |
| 82 | |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 83 | /** |
| 84 | * Construct a target completion event for a failed target, with the given non-empty root causes. |
| 85 | */ |
Klaus Aehlig | d1f4a16 | 2016-10-25 14:51:55 +0000 | [diff] [blame] | 86 | public static TargetCompleteEvent createFailed(ConfiguredTarget ct, NestedSet<Cause> rootCauses) { |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 87 | Preconditions.checkArgument(!Iterables.isEmpty(rootCauses)); |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 88 | return new TargetCompleteEvent( |
| 89 | ct, rootCauses, ImmutableList.<ArtifactsInOutputGroup>of(), false); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 90 | } |
| 91 | |
| 92 | /** |
| 93 | * Returns the target associated with the event. |
| 94 | */ |
| 95 | public ConfiguredTarget getTarget() { |
| 96 | return target; |
| 97 | } |
| 98 | |
| 99 | /** |
| 100 | * Determines whether the target has failed or succeeded. |
| 101 | */ |
| 102 | public boolean failed() { |
| 103 | return !rootCauses.isEmpty(); |
| 104 | } |
| 105 | |
Klaus Aehlig | d1f4a16 | 2016-10-25 14:51:55 +0000 | [diff] [blame] | 106 | /** Get the root causes of the target. May be empty. */ |
| 107 | public Iterable<Cause> getRootCauses() { |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 108 | return rootCauses; |
| 109 | } |
Klaus Aehlig | 8a8a7fc | 2016-10-26 14:27:48 +0000 | [diff] [blame] | 110 | |
| 111 | @Override |
| 112 | public BuildEventId getEventId() { |
| 113 | return BuildEventId.targetCompleted(getTarget().getLabel()); |
| 114 | } |
| 115 | |
| 116 | @Override |
| 117 | public Collection<BuildEventId> getChildrenEvents() { |
| 118 | ImmutableList.Builder childrenBuilder = ImmutableList.builder(); |
| 119 | for (Cause cause : getRootCauses()) { |
| 120 | childrenBuilder.add(BuildEventId.fromCause(cause)); |
| 121 | } |
Klaus Aehlig | 6f97850 | 2016-11-30 12:12:56 +0000 | [diff] [blame] | 122 | if (isTest) { |
Klaus Aehlig | 1f452c3 | 2017-02-02 10:19:15 +0000 | [diff] [blame] | 123 | // For tests, announce all the test actions that will minimally happen (except for |
| 124 | // interruption). If after the result of a test action another attempt is necessary, |
| 125 | // it will be announced with the action that made the new attempt necessary. |
| 126 | Label label = target.getTarget().getLabel(); |
| 127 | TestProvider.TestParams params = target.getProvider(TestProvider.class).getTestParams(); |
| 128 | for (int run = 0; run < Math.max(params.getRuns(), 1); run++) { |
| 129 | for (int shard = 0; shard < Math.max(params.getShards(), 1); shard++) { |
| 130 | childrenBuilder.add(BuildEventId.testResult(label, run, shard)); |
| 131 | } |
| 132 | } |
| 133 | childrenBuilder.add(BuildEventId.testSummary(label)); |
Klaus Aehlig | 8d25362 | 2016-11-02 17:24:46 +0000 | [diff] [blame] | 134 | } |
Klaus Aehlig | 8a8a7fc | 2016-10-26 14:27:48 +0000 | [diff] [blame] | 135 | return childrenBuilder.build(); |
| 136 | } |
| 137 | |
| 138 | @Override |
aehlig | 617bb89 | 2017-04-04 15:03:23 +0000 | [diff] [blame] | 139 | public BuildEventStreamProtos.BuildEvent asStreamProto(BuildEventConverters converters) { |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 140 | BuildEventStreamProtos.TargetComplete.Builder builder = |
| 141 | BuildEventStreamProtos.TargetComplete.newBuilder(); |
| 142 | |
| 143 | builder.setSuccess(!failed()); |
| 144 | builder.addAllTag(getTags()); |
Klaus Aehlig | 4901d8b | 2017-04-10 15:13:59 +0000 | [diff] [blame^] | 145 | builder.addAllOutputGroup(getOutputFilesByGroup(converters.artifactGroupNamer())); |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 146 | |
| 147 | BuildEventStreamProtos.TargetComplete complete = builder.build(); |
Klaus Aehlig | 8a8a7fc | 2016-10-26 14:27:48 +0000 | [diff] [blame] | 148 | return GenericBuildEvent.protoChaining(this).setCompleted(complete).build(); |
| 149 | } |
Klaus Aehlig | 74d716b | 2016-11-23 12:38:24 +0000 | [diff] [blame] | 150 | |
| 151 | @Override |
| 152 | public Collection<BuildEventId> postedAfter() { |
| 153 | return postedAfter; |
| 154 | } |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 155 | |
Klaus Aehlig | 4901d8b | 2017-04-10 15:13:59 +0000 | [diff] [blame^] | 156 | @Override |
| 157 | public Collection<NestedSet<Artifact>> reportedArtifacts() { |
| 158 | ImmutableSet.Builder<NestedSet<Artifact>> builder = |
| 159 | new ImmutableSet.Builder<NestedSet<Artifact>>(); |
| 160 | for (ArtifactsInOutputGroup artifactsInGroup : outputs) { |
| 161 | builder.add(artifactsInGroup.getArtifacts()); |
| 162 | } |
| 163 | return builder.build(); |
| 164 | } |
| 165 | |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 166 | private Iterable<String> getTags() { |
| 167 | // We are only interested in targets that are rules. |
| 168 | if (!(target instanceof RuleConfiguredTarget)) { |
| 169 | return ImmutableList.<String>of(); |
| 170 | } |
| 171 | AttributeMap attributes = ConfiguredAttributeMapper.of((RuleConfiguredTarget) target); |
| 172 | // Every rule (implicitly) has a "tags" attribute. |
| 173 | return attributes.get("tags", Type.STRING_LIST); |
| 174 | } |
| 175 | |
Klaus Aehlig | 4901d8b | 2017-04-10 15:13:59 +0000 | [diff] [blame^] | 176 | private Iterable<OutputGroup> getOutputFilesByGroup(ArtifactGroupNamer namer) { |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 177 | ImmutableList.Builder<OutputGroup> groups = ImmutableList.builder(); |
| 178 | for (ArtifactsInOutputGroup artifactsInOutputGroup : outputs) { |
| 179 | OutputGroup.Builder groupBuilder = OutputGroup.newBuilder(); |
| 180 | groupBuilder.setName(artifactsInOutputGroup.getOutputGroup()); |
Klaus Aehlig | 4901d8b | 2017-04-10 15:13:59 +0000 | [diff] [blame^] | 181 | groupBuilder.addFileSets( |
| 182 | namer.apply( |
| 183 | (new NestedSetView<Artifact>(artifactsInOutputGroup.getArtifacts())).identifier())); |
Jakob Buchgraber | fb64609 | 2017-02-27 18:53:25 +0000 | [diff] [blame] | 184 | groups.add(groupBuilder.build()); |
| 185 | } |
| 186 | return groups.build(); |
| 187 | } |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 188 | } |