private List<Action> evaluate(SpawnActionTemplate spawnActionTemplate) throws Exception {
   SkyKey skyKey = ActionTemplateExpansionValue.key(spawnActionTemplate);
   EvaluationResult<ActionTemplateExpansionValue> result =
       driver.evaluate(
           ImmutableList.of(skyKey),
           false,
           SkyframeExecutor.DEFAULT_THREAD_COUNT,
           NullEventHandler.INSTANCE);
   if (result.hasError()) {
     throw result.getError().getException();
   }
   return ImmutableList.copyOf(result.get(skyKey).getExpandedActions());
 }
  private WalkableGraph getGraphFromPatternsEvaluation(
      ImmutableList<String> patternSequence, boolean successExpected, boolean keepGoing)
      throws InterruptedException {
    SkyKey independentTarget = PrepareDepsOfPatternsValue.key(patternSequence, "");
    ImmutableList<SkyKey> singletonTargetPattern = ImmutableList.of(independentTarget);

    // When PrepareDepsOfPatternsFunction completes evaluation,
    EvaluationResult<SkyValue> evaluationResult =
        getSkyframeExecutor()
            .getDriverForTesting()
            .evaluate(singletonTargetPattern, keepGoing, LOADING_PHASE_THREADS, eventCollector);
    // The evaluation has no errors if success was expected.
    assertThat(evaluationResult.hasError()).isNotEqualTo(successExpected);
    return Preconditions.checkNotNull(evaluationResult.getWalkableGraph());
  }
Example #3
0
  private void init() throws InterruptedException {
    EvaluationResult<SkyValue> result;
    try (AutoProfiler p = AutoProfiler.logged("evaluation and walkable graph", LOG)) {
      result =
          graphFactory.prepareAndGet(
              universeScope, parserPrefix, loadingPhaseThreads, eventHandler);
    }
    graph = result.getWalkableGraph();

    SkyKey universeKey = graphFactory.getUniverseKey(universeScope, parserPrefix);
    universeTargetPatternKeys =
        PrepareDepsOfPatternsFunction.getTargetPatternKeys(
            PrepareDepsOfPatternsFunction.getSkyKeys(universeKey, eventHandler));

    // The prepareAndGet call above evaluates a single PrepareDepsOfPatterns SkyKey.
    // We expect to see either a single successfully evaluated value or a cycle in the result.
    Collection<SkyValue> values = result.values();
    if (!values.isEmpty()) {
      Preconditions.checkState(
          values.size() == 1,
          "Universe query \"%s\" returned multiple" + " values unexpectedly (%s values in result)",
          universeScope,
          values.size());
      Preconditions.checkNotNull(result.get(universeKey), result);
    } else {
      // No values in the result, so there must be an error. We expect the error to be a cycle.
      boolean foundCycle = !Iterables.isEmpty(result.getError().getCycleInfo());
      Preconditions.checkState(
          foundCycle,
          "Universe query \"%s\" failed with non-cycle error: %s",
          universeScope,
          result.getError());
    }
  }
Example #4
0
  /**
   * Analyzes the specified targets using Skyframe as the driving framework.
   *
   * @return the configured targets that should be built along with a WalkableGraph of the analysis.
   */
  public SkyframeAnalysisResult configureTargets(
      EventHandler eventHandler,
      List<ConfiguredTargetKey> values,
      List<AspectValueKey> aspectKeys,
      EventBus eventBus,
      boolean keepGoing)
      throws InterruptedException, ViewCreationFailedException {
    enableAnalysis(true);
    EvaluationResult<ActionLookupValue> result;
    try {
      result = skyframeExecutor.configureTargets(eventHandler, values, aspectKeys, keepGoing);
    } finally {
      enableAnalysis(false);
    }
    ImmutableMap<Action, ConflictException> badActions = skyframeExecutor.findArtifactConflicts();

    Collection<AspectValue> goodAspects = Lists.newArrayListWithCapacity(values.size());
    NestedSetBuilder<Package> packages = NestedSetBuilder.stableOrder();
    for (AspectValueKey aspectKey : aspectKeys) {
      AspectValue value = (AspectValue) result.get(AspectValue.key(aspectKey));
      if (value == null) {
        // Skip aspects that couldn't be applied to targets.
        continue;
      }
      goodAspects.add(value);
      packages.addTransitive(value.getTransitivePackages());
    }

    // Filter out all CTs that have a bad action and convert to a list of configured targets. This
    // code ensures that the resulting list of configured targets has the same order as the incoming
    // list of values, i.e., that the order is deterministic.
    Collection<ConfiguredTarget> goodCts = Lists.newArrayListWithCapacity(values.size());
    for (ConfiguredTargetKey value : values) {
      ConfiguredTargetValue ctValue =
          (ConfiguredTargetValue) result.get(ConfiguredTargetValue.key(value));
      if (ctValue == null) {
        continue;
      }
      goodCts.add(ctValue.getConfiguredTarget());
      packages.addTransitive(ctValue.getTransitivePackages());
    }

    if (!result.hasError() && badActions.isEmpty()) {
      setDeserializedArtifactOwners();
      return new SkyframeAnalysisResult(
          /*hasLoadingError=*/ false,
          /*hasAnalysisError=*/ false,
          ImmutableList.copyOf(goodCts),
          result.getWalkableGraph(),
          ImmutableList.copyOf(goodAspects),
          LoadingPhaseRunner.collectPackageRoots(packages.build().toCollection()));
    }

    // --nokeep_going so we fail with an exception for the first error.
    // TODO(bazel-team): We might want to report the other errors through the event bus but
    // for keeping this code in parity with legacy we just report the first error for now.
    if (!keepGoing) {
      for (Map.Entry<Action, ConflictException> bad : badActions.entrySet()) {
        ConflictException ex = bad.getValue();
        try {
          ex.rethrowTyped();
        } catch (MutableActionGraph.ActionConflictException ace) {
          ace.reportTo(eventHandler);
          String errorMsg =
              "Analysis of target '"
                  + bad.getKey().getOwner().getLabel()
                  + "' failed; build aborted";
          throw new ViewCreationFailedException(errorMsg);
        } catch (ArtifactPrefixConflictException apce) {
          eventHandler.handle(Event.error(apce.getMessage()));
        }
        throw new ViewCreationFailedException(ex.getMessage());
      }

      Map.Entry<SkyKey, ErrorInfo> error = result.errorMap().entrySet().iterator().next();
      SkyKey topLevel = error.getKey();
      ErrorInfo errorInfo = error.getValue();
      assertSaneAnalysisError(errorInfo, topLevel);
      skyframeExecutor
          .getCyclesReporter()
          .reportCycles(errorInfo.getCycleInfo(), topLevel, eventHandler);
      Throwable cause = errorInfo.getException();
      Preconditions.checkState(
          cause != null || !Iterables.isEmpty(errorInfo.getCycleInfo()), errorInfo);
      String errorMsg = null;
      if (topLevel.argument() instanceof ConfiguredTargetKey) {
        errorMsg =
            "Analysis of target '"
                + ConfiguredTargetValue.extractLabel(topLevel)
                + "' failed; build aborted";
      } else if (topLevel.argument() instanceof AspectValueKey) {
        AspectValueKey aspectKey = (AspectValueKey) topLevel.argument();
        errorMsg = "Analysis of aspect '" + aspectKey.getDescription() + "' failed; build aborted";
      } else {
        assert false;
      }
      if (cause instanceof ActionConflictException) {
        ((ActionConflictException) cause).reportTo(eventHandler);
      }
      throw new ViewCreationFailedException(errorMsg);
    }

    boolean hasLoadingError = false;
    // --keep_going : We notify the error and return a ConfiguredTargetValue
    for (Map.Entry<SkyKey, ErrorInfo> errorEntry : result.errorMap().entrySet()) {
      // Only handle errors of configured targets, not errors of top-level aspects.
      // TODO(ulfjack): this is quadratic - if there are a lot of CTs, this could be rather slow.
      if (!values.contains(errorEntry.getKey().argument())) {
        continue;
      }
      SkyKey errorKey = errorEntry.getKey();
      ConfiguredTargetKey label = (ConfiguredTargetKey) errorKey.argument();
      Label topLevelLabel = label.getLabel();
      ErrorInfo errorInfo = errorEntry.getValue();
      assertSaneAnalysisError(errorInfo, errorKey);

      skyframeExecutor
          .getCyclesReporter()
          .reportCycles(errorInfo.getCycleInfo(), errorKey, eventHandler);
      Exception cause = errorInfo.getException();
      Label analysisRootCause = null;
      if (cause instanceof ConfiguredValueCreationException) {
        ConfiguredValueCreationException ctCause = (ConfiguredValueCreationException) cause;
        for (Label rootCause : ctCause.getRootCauses()) {
          hasLoadingError = true;
          eventBus.post(new LoadingFailureEvent(topLevelLabel, rootCause));
        }
        analysisRootCause = ctCause.getAnalysisRootCause();
      } else if (!Iterables.isEmpty(errorInfo.getCycleInfo())) {
        analysisRootCause =
            maybeGetConfiguredTargetCycleCulprit(topLevelLabel, errorInfo.getCycleInfo());
      } else if (cause instanceof ActionConflictException) {
        ((ActionConflictException) cause).reportTo(eventHandler);
      }
      eventHandler.handle(
          Event.warn(
              "errors encountered while analyzing target '"
                  + topLevelLabel
                  + "': it will not be built"));
      if (analysisRootCause != null) {
        eventBus.post(
            new AnalysisFailureEvent(
                LabelAndConfiguration.of(topLevelLabel, label.getConfiguration()),
                analysisRootCause));
      }
    }

    Collection<Exception> reportedExceptions = Sets.newHashSet();
    for (Map.Entry<Action, ConflictException> bad : badActions.entrySet()) {
      ConflictException ex = bad.getValue();
      try {
        ex.rethrowTyped();
      } catch (MutableActionGraph.ActionConflictException ace) {
        ace.reportTo(eventHandler);
        eventHandler.handle(
            Event.warn(
                "errors encountered while analyzing target '"
                    + bad.getKey().getOwner().getLabel()
                    + "': it will not be built"));
      } catch (ArtifactPrefixConflictException apce) {
        if (reportedExceptions.add(apce)) {
          eventHandler.handle(Event.error(apce.getMessage()));
        }
      }
    }

    if (!badActions.isEmpty()) {
      // In order to determine the set of configured targets transitively error free from action
      // conflict issues, we run a post-processing update() that uses the bad action map.
      EvaluationResult<PostConfiguredTargetValue> actionConflictResult =
          skyframeExecutor.postConfigureTargets(eventHandler, values, keepGoing, badActions);

      goodCts = Lists.newArrayListWithCapacity(values.size());
      for (ConfiguredTargetKey value : values) {
        PostConfiguredTargetValue postCt =
            actionConflictResult.get(PostConfiguredTargetValue.key(value));
        if (postCt != null) {
          goodCts.add(postCt.getCt());
        }
      }
    }
    setDeserializedArtifactOwners();
    return new SkyframeAnalysisResult(
        hasLoadingError,
        result.hasError() || !badActions.isEmpty(),
        ImmutableList.copyOf(goodCts),
        result.getWalkableGraph(),
        ImmutableList.copyOf(goodAspects),
        LoadingPhaseRunner.collectPackageRoots(packages.build().toCollection()));
  }
Example #5
0
  /**
   * Analyzes the specified targets using Skyframe as the driving framework.
   *
   * @return the configured targets that should be built along with a WalkableGraph of the analysis.
   */
  public SkyframeAnalysisResult configureTargets(
      List<ConfiguredTargetKey> values,
      List<AspectKey> aspectKeys,
      EventBus eventBus,
      boolean keepGoing)
      throws InterruptedException, ViewCreationFailedException {
    enableAnalysis(true);
    EvaluationResult<ActionLookupValue> result;
    try {
      result = skyframeExecutor.configureTargets(values, aspectKeys, keepGoing);
    } finally {
      enableAnalysis(false);
    }
    ImmutableMap<Action, ConflictException> badActions = skyframeExecutor.findArtifactConflicts();

    Collection<AspectValue> goodAspects = Lists.newArrayListWithCapacity(values.size());
    for (AspectKey aspectKey : aspectKeys) {
      AspectValue value = (AspectValue) result.get(AspectValue.key(aspectKey));
      if (value == null) {
        // Skip aspects that couldn't be applied to targets.
        continue;
      }
      goodAspects.add(value);
    }

    // Filter out all CTs that have a bad action and convert to a list of configured targets. This
    // code ensures that the resulting list of configured targets has the same order as the incoming
    // list of values, i.e., that the order is deterministic.
    Collection<ConfiguredTarget> goodCts = Lists.newArrayListWithCapacity(values.size());
    for (ConfiguredTargetKey value : values) {
      ConfiguredTargetValue ctValue =
          (ConfiguredTargetValue) result.get(ConfiguredTargetValue.key(value));
      if (ctValue == null) {
        continue;
      }
      goodCts.add(ctValue.getConfiguredTarget());
    }

    if (!result.hasError() && badActions.isEmpty()) {
      setDeserializedArtifactOwners();
      return new SkyframeAnalysisResult(
          ImmutableList.copyOf(goodCts),
          result.getWalkableGraph(),
          ImmutableList.copyOf(goodAspects));
    }

    // --nokeep_going so we fail with an exception for the first error.
    // TODO(bazel-team): We might want to report the other errors through the event bus but
    // for keeping this code in parity with legacy we just report the first error for now.
    if (!keepGoing) {
      for (Map.Entry<Action, ConflictException> bad : badActions.entrySet()) {
        ConflictException ex = bad.getValue();
        try {
          ex.rethrowTyped();
        } catch (MutableActionGraph.ActionConflictException ace) {
          ace.reportTo(skyframeExecutor.getReporter());
          String errorMsg =
              "Analysis of target '"
                  + bad.getKey().getOwner().getLabel()
                  + "' failed; build aborted";
          throw new ViewCreationFailedException(errorMsg);
        } catch (ArtifactPrefixConflictException apce) {
          skyframeExecutor.getReporter().handle(Event.error(apce.getMessage()));
        }
        throw new ViewCreationFailedException(ex.getMessage());
      }

      Map.Entry<SkyKey, ErrorInfo> error = result.errorMap().entrySet().iterator().next();
      SkyKey topLevel = error.getKey();
      ErrorInfo errorInfo = error.getValue();
      assertSaneAnalysisError(errorInfo, topLevel);
      skyframeExecutor
          .getCyclesReporter()
          .reportCycles(errorInfo.getCycleInfo(), topLevel, skyframeExecutor.getReporter());
      Throwable cause = errorInfo.getException();
      Preconditions.checkState(
          cause != null || !Iterables.isEmpty(errorInfo.getCycleInfo()), errorInfo);
      String errorMsg =
          "Analysis of target '"
              + ConfiguredTargetValue.extractLabel(topLevel)
              + "' failed; build aborted";
      if (cause instanceof ActionConflictException) {
        ((ActionConflictException) cause).reportTo(skyframeExecutor.getReporter());
      }
      throw new ViewCreationFailedException(errorMsg);
    }

    // --keep_going : We notify the error and return a ConfiguredTargetValue
    for (Map.Entry<SkyKey, ErrorInfo> errorEntry : result.errorMap().entrySet()) {
      if (values.contains(errorEntry.getKey().argument())) {
        SkyKey errorKey = errorEntry.getKey();
        ConfiguredTargetKey label = (ConfiguredTargetKey) errorKey.argument();
        ErrorInfo errorInfo = errorEntry.getValue();
        assertSaneAnalysisError(errorInfo, errorKey);

        skyframeExecutor
            .getCyclesReporter()
            .reportCycles(errorInfo.getCycleInfo(), errorKey, skyframeExecutor.getReporter());
        // We try to get the root cause key first from ErrorInfo rootCauses. If we don't have one
        // we try to use the cycle culprit if the error is a cycle. Otherwise we use the top-level
        // error key.
        Label root;
        if (!Iterables.isEmpty(errorEntry.getValue().getRootCauses())) {
          SkyKey culprit =
              Preconditions.checkNotNull(
                  Iterables.getFirst(errorEntry.getValue().getRootCauses(), null));
          root = ((ConfiguredTargetKey) culprit.argument()).getLabel();
        } else {
          root = maybeGetConfiguredTargetCycleCulprit(errorInfo.getCycleInfo());
        }
        Exception cause = errorInfo.getException();
        if (cause instanceof ActionConflictException) {
          ((ActionConflictException) cause).reportTo(skyframeExecutor.getReporter());
        }
        skyframeExecutor
            .getReporter()
            .handle(
                Event.warn(
                    "errors encountered while analyzing target '"
                        + label.getLabel()
                        + "': it will not be built"));
        eventBus.post(
            new AnalysisFailureEvent(
                LabelAndConfiguration.of(label.getLabel(), label.getConfiguration()), root));
      }
    }

    Collection<Exception> reportedExceptions = Sets.newHashSet();
    for (Map.Entry<Action, ConflictException> bad : badActions.entrySet()) {
      ConflictException ex = bad.getValue();
      try {
        ex.rethrowTyped();
      } catch (MutableActionGraph.ActionConflictException ace) {
        ace.reportTo(skyframeExecutor.getReporter());
        skyframeExecutor
            .getReporter()
            .handle(
                Event.warn(
                    "errors encountered while analyzing target '"
                        + bad.getKey().getOwner().getLabel()
                        + "': it will not be built"));
      } catch (ArtifactPrefixConflictException apce) {
        if (reportedExceptions.add(apce)) {
          skyframeExecutor.getReporter().handle(Event.error(apce.getMessage()));
        }
      }
    }

    if (!badActions.isEmpty()) {
      // In order to determine the set of configured targets transitively error free from action
      // conflict issues, we run a post-processing update() that uses the bad action map.
      EvaluationResult<PostConfiguredTargetValue> actionConflictResult =
          skyframeExecutor.postConfigureTargets(values, keepGoing, badActions);

      goodCts = Lists.newArrayListWithCapacity(values.size());
      for (ConfiguredTargetKey value : values) {
        PostConfiguredTargetValue postCt =
            actionConflictResult.get(PostConfiguredTargetValue.key(value));
        if (postCt != null) {
          goodCts.add(postCt.getCt());
        }
      }
    }
    setDeserializedArtifactOwners();
    return new SkyframeAnalysisResult(
        ImmutableList.copyOf(goodCts),
        result.getWalkableGraph(),
        ImmutableList.copyOf(goodAspects));
  }