// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.devtools.build.lib.analysis;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ObjectArrays;
import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.BuildOptionsView;
import com.google.devtools.build.lib.analysis.config.Fragment;
import com.google.devtools.build.lib.analysis.config.FragmentOptions;
import com.google.devtools.build.lib.analysis.config.RequiresOptions;
import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition;
import com.google.devtools.build.lib.analysis.util.AnalysisCachingTestBase;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.rules.java.JavaInfo;
import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider;
import com.google.devtools.build.lib.testutil.TestConstants.InternalTestExecutionMode;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDefinition;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
import com.google.devtools.common.options.OptionsParser;
import java.io.IOException;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.starlark.java.annot.StarlarkBuiltin;
import net.starlark.java.eval.StarlarkValue;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Analysis caching tests. */
@RunWith(JUnit4.class)
public class AnalysisCachingTest extends AnalysisCachingTestBase {

  @Before
  public void setup() throws Exception {
    useConfiguration();
  }

  @Override
  public void useConfiguration(String... args) throws Exception {
    super.useConfiguration(ObjectArrays.concat(args, "--experimental_google_legacy_api"));
  }

  @Test
  public void testSimpleCleanAnalysis() throws Exception {
    scratch.file("java/a/BUILD", "java_test(name = 'A',", "          srcs = ['A.java'])");
    update("//java/a:A");
    ConfiguredTarget javaTest = getConfiguredTarget("//java/a:A");
    assertThat(javaTest).isNotNull();
    assertThat(JavaInfo.getProvider(JavaSourceJarsProvider.class, javaTest)).isNotNull();
  }

  @Test
  public void testTickTock() throws Exception {
    scratch.file(
        "java/a/BUILD",
        "java_test(name = 'A',",
        "          srcs = ['A.java'])",
        "java_test(name = 'B',",
        "          srcs = ['B.java'])");
    update("//java/a:A");
    update("//java/a:B");
    update("//java/a:A");
  }

  @Test
  public void testFullyCached() throws Exception {
    scratch.file("java/a/BUILD", "java_test(name = 'A',", "          srcs = ['A.java'])");
    update("//java/a:A");
    ConfiguredTarget old = getConfiguredTarget("//java/a:A");
    update("//java/a:A");
    ConfiguredTarget current = getConfiguredTarget("//java/a:A");
    assertThat(current).isSameInstanceAs(old);
  }

  @Test
  public void testSubsetCached() throws Exception {
    scratch.file(
        "java/a/BUILD",
        "java_test(name = 'A',",
        "          srcs = ['A.java'])",
        "java_test(name = 'B',",
        "          srcs = ['B.java'])");
    update("//java/a:A", "//java/a:B");
    ConfiguredTarget old = getConfiguredTarget("//java/a:A");
    update("//java/a:A");
    ConfiguredTarget current = getConfiguredTarget("//java/a:A");
    assertThat(current).isSameInstanceAs(old);
  }

  @Test
  public void testDependencyChanged() throws Exception {
    scratch.file(
        "java/a/BUILD",
        "java_test(name = 'A',",
        "          srcs = ['A.java'],",
        "          deps = ['//java/b'])");
    scratch.file("java/b/BUILD", "java_library(name = 'b',", "             srcs = ['B.java'])");
    update("//java/a:A");
    ConfiguredTarget old = getConfiguredTarget("//java/a:A");
    scratch.overwriteFile(
        "java/b/BUILD", "java_library(name = 'b',", "             srcs = ['C.java'])");
    update("//java/a:A");
    ConfiguredTarget current = getConfiguredTarget("//java/a:A");
    assertThat(current).isNotSameInstanceAs(old);
  }

  @Test
  public void testAspectHintsChanged() throws Exception {
    useConfiguration("--experimental_enable_aspect_hints");
    scratch.file(
        "foo/rule.bzl",
        "def _rule_impl(ctx):",
        "    return []",
        "my_rule = rule(",
        "    implementation = _rule_impl,",
        "    attrs = {",
        "        'deps': attr.label_list(),",
        "        'srcs': attr.label_list(allow_files = True)",
        "    },",
        ")");
    scratch.file(
        "foo/BUILD",
        "load('//foo:rule.bzl', 'my_rule')",
        "my_rule(name = 'foo', deps = [':bar'])",
        "my_rule(name = 'bar', aspect_hints = ['//aspect_hint:hint'])");
    scratch.file(
        "aspect_hint/BUILD",
        "load('//foo:rule.bzl', 'my_rule')",
        "my_rule(name = 'hint', srcs = ['baz.h'])");

    update("//foo:foo");
    ConfiguredTarget old = getConfiguredTarget("//foo:foo");
    scratch.overwriteFile(
        "aspect_hint/BUILD",
        "load('//foo:rule.bzl', 'my_rule')",
        "my_rule(name = 'hint', srcs = ['qux.h'])");
    update("//foo:foo");
    ConfiguredTarget current = getConfiguredTarget("//foo:foo");

    assertThat(current).isNotSameInstanceAs(old);
  }

  @Test
  public void testTopLevelChanged() throws Exception {
    scratch.file(
        "java/a/BUILD",
        "java_test(name = 'A',",
        "          srcs = ['A.java'],",
        "          deps = ['//java/b'])");
    scratch.file("java/b/BUILD", "java_library(name = 'b',", "             srcs = ['B.java'])");
    update("//java/a:A");
    ConfiguredTarget old = getConfiguredTarget("//java/a:A");
    scratch.overwriteFile("java/a/BUILD", "java_test(name = 'A',", "          srcs = ['A.java'])");
    update("//java/a:A");
    ConfiguredTarget current = getConfiguredTarget("//java/a:A");
    assertThat(current).isNotSameInstanceAs(old);
  }

  // Regression test for:
  // "action conflict detection is incorrect if conflict is in non-top-level configured targets".
  @Test
  public void testActionConflictInDependencyImpliesTopLevelTargetFailure() throws Exception {
    if (getInternalTestExecutionMode() != InternalTestExecutionMode.NORMAL) {
      // TODO(b/67529176): conflicts not detected.
      return;
    }
    useConfiguration("--cpu=k8");
    scratch.file(
        "conflict/BUILD",
        "cc_library(name='x', srcs=['foo.cc'])",
        "cc_binary(name='_objs/x/foo.o', srcs=['bar.cc'])",
        "cc_binary(name='foo', deps=['x'], data=['_objs/x/foo.o'])");
    reporter.removeHandler(failFastHandler); // expect errors
    update(defaultFlags().with(Flag.KEEP_GOING), "//conflict:foo");
    assertContainsEvent("file 'conflict/_objs/x/foo.o' " + CONFLICT_MSG);
    assertThat(getAnalysisResult().getTargetsToBuild()).isEmpty();
  }

  /**
   * Generating the same output from two targets is ok if we build them on successive builds and
   * invalidate the first target before we build the second target. This is a strictly weaker test
   * than if we didn't invalidate the first target, but since Skyframe can't pass then, this test
   * could be useful for it. Actually, since Skyframe makes multiple update calls, it manages to
   * unregister actions even when it shouldn't, and so this test can incorrectly pass. However,
   * {@code SkyframeExecutorTest#testNoActionConflictWithInvalidatedTarget} tests it more
   * rigorously.
   */
  @Test
  public void testNoActionConflictWithInvalidatedTarget() throws Exception {
    useConfiguration("--cpu=k8");
    scratch.file(
        "conflict/BUILD",
        "cc_library(name='x', srcs=['foo.cc'])",
        "cc_binary(name='_objs/x/foo.o', srcs=['bar.cc'])");
    update("//conflict:x");
    ConfiguredTarget conflict = getConfiguredTarget("//conflict:x");
    Action oldAction = getGeneratingAction(getBinArtifact("_objs/x/foo.o", conflict));
    assertThat(oldAction.getOwner().getLabel().toString()).isEqualTo("//conflict:x");
    scratch.overwriteFile(
        "conflict/BUILD",
        "cc_library(name='newx', srcs=['foo.cc'])", // Rename target.
        "cc_binary(name='_objs/x/foo.o', srcs=['bar.cc'])");
    update(defaultFlags(), "//conflict:_objs/x/foo.o");
    ConfiguredTarget objsConflict = getConfiguredTarget("//conflict:_objs/x/foo.o");
    Action newAction = getGeneratingAction(getBinArtifact("_objs/x/foo.o", objsConflict));
    assertThat(newAction.getOwner().getLabel().toString()).isEqualTo("//conflict:_objs/x/foo.o");
  }

  /** Generating the same output from multiple actions is causing an error. */
  @Test
  public void testActionConflictCausesError() throws Exception {
    if (getInternalTestExecutionMode() != InternalTestExecutionMode.NORMAL) {
      // TODO(b/67529176): conflicts not detected.
      return;
    }
    useConfiguration("--cpu=k8");
    scratch.file(
        "conflict/BUILD",
        "cc_library(name='x', srcs=['foo.cc'])",
        "cc_binary(name='_objs/x/foo.o', srcs=['bar.cc'])");
    reporter.removeHandler(failFastHandler); // expect errors
    update(defaultFlags().with(Flag.KEEP_GOING), "//conflict:x", "//conflict:_objs/x/foo.o");
    assertContainsEvent("file 'conflict/_objs/x/foo.o' " + CONFLICT_MSG);
  }

  @Test
  public void testNoActionConflictErrorAfterClearedAnalysis() throws Exception {
    if (getInternalTestExecutionMode() != InternalTestExecutionMode.NORMAL) {
      // TODO(b/67529176): conflicts not detected.
      return;
    }
    useConfiguration("--cpu=k8");
    scratch.file(
        "conflict/BUILD",
        "cc_library(name='x', srcs=['foo.cc'])",
        "cc_binary(name='_objs/x/foo.o', srcs=['bar.cc'])");
    reporter.removeHandler(failFastHandler); // expect errors
    update(defaultFlags().with(Flag.KEEP_GOING), "//conflict:x", "//conflict:_objs/x/foo.o");
    // We want to force a "dropConfiguredTargetsNow" operation, which won't inform the
    // invalidation receiver about the dropped configured targets.
    skyframeExecutor.clearAnalysisCache(ImmutableSet.of(), ImmutableSet.of());
    assertContainsEvent("file 'conflict/_objs/x/foo.o' " + CONFLICT_MSG);
    eventCollector.clear();
    scratch.overwriteFile(
        "conflict/BUILD",
        "cc_library(name='x', srcs=['baz.cc'])",
        "cc_binary(name='_objs/x/foo.o', srcs=['bar.cc'])");
    update(defaultFlags().with(Flag.KEEP_GOING), "//conflict:x", "//conflict:_objs/x/foo.o");
    assertNoEvents();
  }

  /**
   * For two conflicting actions whose primary inputs are different, no list diff detail should be
   * part of the output.
   */
  @Test
  public void testConflictingArtifactsErrorWithNoListDetail() throws Exception {
    if (getInternalTestExecutionMode() != InternalTestExecutionMode.NORMAL) {
      // TODO(b/67529176): conflicts not detected.
      return;
    }
    useConfiguration("--cpu=k8");
    scratch.file(
        "conflict/BUILD",
        "cc_library(name='x', srcs=['foo.cc'])",
        "cc_binary(name='_objs/x/foo.o', srcs=['bar.cc'])");
    reporter.removeHandler(failFastHandler); // expect errors
    update(defaultFlags().with(Flag.KEEP_GOING), "//conflict:x", "//conflict:_objs/x/foo.o");

    assertContainsEvent("file 'conflict/_objs/x/foo.o' " + CONFLICT_MSG);
    assertDoesNotContainEvent("MandatoryInputs");
    assertDoesNotContainEvent("Outputs");
  }

  /**
   * For two conflicted actions whose primary inputs are the same, list diff (max 5) should be part
   * of the output.
   */
  @Test
  public void testConflictingArtifactsWithListDetail() throws Exception {
    if (getInternalTestExecutionMode() != InternalTestExecutionMode.NORMAL) {
      // TODO(b/67529176): conflicts not detected.
      return;
    }
    useConfiguration("--cpu=k8");
    scratch.file(
        "conflict/BUILD",
        "cc_library(name='x', srcs=['foo1.cc'])",
        "genrule(name = 'foo', outs=['_objs/x/foo1.o'], srcs=['foo1.cc', 'foo2.cc', "
            + "'foo3.cc', 'foo4.cc', 'foo5.cc', 'foo6.cc'], cmd='', output_to_bindir=1)");
    reporter.removeHandler(failFastHandler); // expect errors
    update(defaultFlags().with(Flag.KEEP_GOING), "//conflict:x", "//conflict:foo");

    Event event = assertContainsEvent("file 'conflict/_objs/x/foo1.o' " + CONFLICT_MSG);
    assertContainsEvent("MandatoryInputs");
    assertContainsEvent("Outputs");

    // Validate that maximum of 5 artifacts in MandatoryInputs are part of output.
    Pattern pattern = Pattern.compile("\tconflict\\/foo[2-6].cc");
    Matcher matcher = pattern.matcher(event.getMessage());
    int matchCount = 0;
    while (matcher.find()) {
      matchCount++;
    }

    assertWithMessage(
            "Event does not contain expected number of file conflicts:\n" + event.getMessage())
        .that(matchCount)
        .isEqualTo(5);
  }

  /**
   * The current action conflict detection code will only mark one of the targets as having an
   * error, and with multi-threaded analysis it is not deterministic which one that will be.
   */
  @Test
  public void testActionConflictMarksTargetInvalid() throws Exception {
    if (getInternalTestExecutionMode() != InternalTestExecutionMode.NORMAL) {
      // TODO(b/67529176): conflicts not detected.
      return;
    }
    useConfiguration("--cpu=k8");
    scratch.file(
        "conflict/BUILD",
        "cc_library(name='x', srcs=['foo.cc'])",
        "cc_binary(name='_objs/x/foo.o', srcs=['bar.cc'])");
    reporter.removeHandler(failFastHandler); // expect errors
    int successfulAnalyses =
        update(defaultFlags().with(Flag.KEEP_GOING), "//conflict:x", "//conflict:_objs/x/foo.pic.o")
            .getTargetsToBuild()
            .size();
    assertThat(successfulAnalyses).isEqualTo(1);
  }

  @Test
  public void aliasConflict() throws Exception {
    scratch.file(
        "conflict/conflict.bzl",
        "def _conflict(ctx):",
        "    file = ctx.actions.declare_file('single_file')",
        "    ctx.actions.write(output = file, content = ctx.attr.name)",
        "    return [DefaultInfo(files = depset([file]))]",
        "my_rule = rule(implementation = _conflict)");
    scratch.file(
        "conflict/BUILD",
        "load(':conflict.bzl', 'my_rule')",
        "my_rule(name = 'conflict1')",
        "my_rule(name = 'conflict2')",
        "alias(name = 'aliased', actual = ':conflict2')");
    reporter.removeHandler(failFastHandler);
    assertThrows(
        ViewCreationFailedException.class,
        () -> update("//conflict:conflict1", "//conflict:aliased"));
  }

  @Test
  public void actionConflictFromSameTarget() throws Exception {
    scratch.file(
        "conflict/conflict.bzl",
        "def _conflict(ctx):",
        "    file = ctx.actions.declare_file('single_file')",
        "    ctx.actions.write(output = file, content = 'a')",
        "    ctx.actions.write(output = file, content = 'b')",
        "    return [DefaultInfo(files = depset([file]))]",
        "my_rule = rule(implementation = _conflict)");
    scratch.file(
        "conflict/BUILD", "load(':conflict.bzl', 'my_rule')", "my_rule(name = 'conflict')");
    reporter.removeHandler(failFastHandler);
    assertThrows(ViewCreationFailedException.class, () -> update("//conflict"));
    assertContainsEvent("file 'conflict/single_file' is generated by these conflicting actions:");
  }

  @Test
  public void actionConflictWithDependentRule() throws IOException {
    scratch.file(
        "conflict/conflict.bzl",
        "def _dep(ctx):",
        "    file = ctx.actions.declare_file('file')",
        "    ctx.actions.write(output = file, content = '')",
        "    return [DefaultInfo(files = depset([file]))]",
        "",
        "dep_rule = rule(implementation = _dep)",
        "def _top(ctx):",
        "    file = ctx.file.src",
        "    ctx.actions.write(output = file, content = '')",
        "    return [DefaultInfo(files = depset([file]))]",
        "",
        "top_rule = rule(",
        "                implementation = _top,",
        "                attrs = {'src': attr.label(mandatory=True, allow_single_file = True)}",
        "           )");
    scratch.file(
        "conflict/BUILD",
        "load(':conflict.bzl', 'top_rule', 'dep_rule')",
        "top_rule(name = 'top', src = ':dep')",
        "dep_rule(name = 'dep')");
    reporter.removeHandler(failFastHandler);

    assertThrows(ViewCreationFailedException.class, () -> update("//conflict:top"));

    assertContainsEvent(
        "in top_rule rule //conflict:top: File 'conflict/file' is produced by action 'Writing file"
            + " conflict/file' but is already generated by rule //conflict:dep");
  }

  /** BUILD file involved in BUILD-file cycle is changed */
  @Test
  public void testBuildFileInCycleChanged() throws Exception {
    if (getInternalTestExecutionMode() != InternalTestExecutionMode.NORMAL) {
      // TODO(b/67412276): cycles not properly handled.
      return;
    }
    scratch.file(
        "java/a/BUILD",
        "java_test(name = 'A',",
        "          srcs = ['A.java'],",
        "          deps = ['//java/b'])");
    scratch.file(
        "java/b/BUILD",
        "java_library(name = 'b',",
        "          srcs = ['B.java'],",
        "          deps = ['//java/c'])");
    scratch.file(
        "java/c/BUILD",
        "java_library(name = 'c',",
        "          srcs = ['C.java'],",
        "          deps = ['//java/b'])");
    // expect error
    reporter.removeHandler(failFastHandler);
    update(defaultFlags().with(Flag.KEEP_GOING), "//java/a:A");
    ConfiguredTarget old = getConfiguredTarget("//java/a:A");
    // drop dependency on from b to c
    scratch.overwriteFile(
        "java/b/BUILD", "java_library(name = 'b',", "             srcs = ['B.java'])");
    eventCollector.clear();
    reporter.addHandler(failFastHandler);
    update("//java/a:A");
    ConfiguredTarget current = getConfiguredTarget("//java/a:A");
    assertThat(current).isNotSameInstanceAs(old);
  }

  private void assertNoTargetsVisited() {
    Set<?> analyzedTargets = getSkyframeEvaluatedTargetKeys();
    assertWithMessage(analyzedTargets.toString()).that(analyzedTargets.size()).isEqualTo(0);
  }

  @Test
  public void testSecondRunAllCacheHits() throws Exception {
    scratch.file("java/a/BUILD", "java_test(name = 'A',", "          srcs = ['A.java'])");
    update("//java/a:A");
    update("//java/a:A");
    assertNoTargetsVisited();
  }

  @Test
  public void testDependencyAllCacheHits() throws Exception {
    scratch.file(
        "java/a/BUILD",
        "java_library(name = 'x', srcs = ['A.java'], deps = ['y'])",
        "java_library(name = 'y', srcs = ['B.java'])");
    update("//java/a:x");
    Set<?> oldAnalyzedTargets = getSkyframeEvaluatedTargetKeys();
    assertThat(oldAnalyzedTargets.size()).isAtLeast(2); // could be greater due to implicit deps
    assertThat(countObjectsPartiallyMatchingRegex(oldAnalyzedTargets, "//java/a:x")).isEqualTo(1);
    assertThat(countObjectsPartiallyMatchingRegex(oldAnalyzedTargets, "//java/a:y")).isEqualTo(1);
    update("//java/a:y");
    assertNoTargetsVisited();
  }

  @Test
  public void testSupersetNotAllCacheHits() throws Exception {
    scratch.file(
        "java/a/BUILD",
        // It's important that all targets are of the same rule class, otherwise the second update
        // call might analyze more than one extra target because of potential implicit dependencies.
        "java_library(name = 'x', srcs = ['A.java'], deps = ['y'])",
        "java_library(name = 'y', srcs = ['B.java'], deps = ['z'])",
        "java_library(name = 'z', srcs = ['C.java'])");
    update("//java/a:y");
    Set<?> oldAnalyzedTargets = getSkyframeEvaluatedTargetKeys();
    assertThat(oldAnalyzedTargets.size()).isAtLeast(3); // could be greater due to implicit deps
    assertThat(countObjectsPartiallyMatchingRegex(oldAnalyzedTargets, "//java/a:x")).isEqualTo(0);
    assertThat(countObjectsPartiallyMatchingRegex(oldAnalyzedTargets, "//java/a:y")).isEqualTo(1);
    update("//java/a:x");
    Set<?> newAnalyzedTargets = getSkyframeEvaluatedTargetKeys();
    // Source target and rule target.
    assertThat(newAnalyzedTargets).hasSize(2);
    assertThat(countObjectsPartiallyMatchingRegex(newAnalyzedTargets, "//java/a:x")).isEqualTo(1);
    assertThat(countObjectsPartiallyMatchingRegex(newAnalyzedTargets, "//java/a:y")).isEqualTo(0);
  }

  @Test
  public void testExtraActions() throws Exception {
    scratch.file("java/com/google/a/BUILD", "java_library(name='a', srcs=['A.java'])");
    scratch.file("java/com/google/b/BUILD", "java_library(name='b', srcs=['B.java'])");
    scratch.file(
        "extra/BUILD",
        "extra_action(name = 'extra',",
        "             out_templates = ['$(OWNER_LABEL_DIGEST)_$(ACTION_ID).tst'],",
        "             cmd = '')",
        "action_listener(name = 'listener',",
        "                mnemonics = ['Javac'],",
        "                extra_actions = [':extra'])");

    useConfiguration("--experimental_action_listener=//extra:listener");
    update("//java/com/google/a:a");
    update("//java/com/google/b:b");
  }

  @Test
  public void testExtraActionsCaching() throws Exception {
    scratch.file("java/a/BUILD", "java_library(name='a', srcs=['A.java'])");
    scratch.file(
        "extra/BUILD",
        "extra_action(name = 'extra',",
        "             out_templates = ['$(OWNER_LABEL_DIGEST)_$(ACTION_ID).tst'],",
        "             cmd = 'echo $(EXTRA_ACTION_FILE)')",
        "action_listener(name = 'listener',",
        "                mnemonics = ['Javac'],",
        "                extra_actions = [':extra'])");
    useConfiguration("--experimental_action_listener=//extra:listener");

    update("//java/a:a");
    getConfiguredTarget("//java/a:a");

    scratch.overwriteFile(
        "extra/BUILD",
        "extra_action(name = 'extra',",
        "             out_templates = ['$(OWNER_LABEL_DIGEST)_$(ACTION_ID).tst'],",
        "             cmd = 'echo $(BUG)')", // <-- change here
        "action_listener(name = 'listener',",
        "                mnemonics = ['Javac'],",
        "                extra_actions = [':extra'])");
    reporter.removeHandler(failFastHandler);
    ViewCreationFailedException e =
        assertThrows(ViewCreationFailedException.class, () -> update("//java/a:a"));
    assertThat(e).hasMessageThat().contains("Analysis of target '//java/a:a' failed");
    assertContainsEvent("$(BUG) not defined");
  }

  @Test
  public void testConfigurationCachingWithWarningReplay() throws Exception {
    useConfiguration("--strip=always", "--copt=-g");
    update();
    assertContainsEvent("Debug information will be generated and then stripped away");
    eventCollector.clear();
    update();
    assertContainsEvent("Debug information will be generated and then stripped away");
  }

  @Test
  public void testSkyframeCacheInvalidationBuildFileChange() throws Exception {
    scratch.file("java/a/BUILD", "java_test(name = 'A',", "          srcs = ['A.java'])");
    String aTarget = "//java/a:A";
    update(aTarget);
    ConfiguredTarget firstCT = getConfiguredTarget(aTarget);

    scratch.overwriteFile("java/a/BUILD", "java_test(name = 'A',", "          srcs = ['B.java'])");

    update(aTarget);
    ConfiguredTarget updatedCT = getConfiguredTarget(aTarget);
    assertThat(updatedCT).isNotSameInstanceAs(firstCT);

    update(aTarget);
    ConfiguredTarget updated2CT = getConfiguredTarget(aTarget);
    assertThat(updated2CT).isSameInstanceAs(updatedCT);
  }

  @Test
  public void testSkyframeDifferentPackagesInvalidation() throws Exception {
    scratch.file("java/a/BUILD", "java_test(name = 'A',", "          srcs = ['A.java'])");

    scratch.file("java/b/BUILD", "java_test(name = 'B',", "          srcs = ['B.java'])");

    String aTarget = "//java/a:A";
    update(aTarget);
    ConfiguredTarget oldAConfTarget = getConfiguredTarget(aTarget);
    String bTarget = "//java/b:B";
    update(bTarget);
    ConfiguredTarget oldBConfTarget = getConfiguredTarget(bTarget);

    scratch.overwriteFile("java/b/BUILD", "java_test(name = 'B',", "          srcs = ['C.java'])");

    update(aTarget);
    // Check that 'A' was not invalidated because 'B' was modified and invalidated.
    ConfiguredTarget newAConfTarget = getConfiguredTarget(aTarget);
    ConfiguredTarget newBConfTarget = getConfiguredTarget(bTarget);

    assertThat(newAConfTarget).isSameInstanceAs(oldAConfTarget);
    assertThat(newBConfTarget).isNotSameInstanceAs(oldBConfTarget);
  }

  private int countObjectsPartiallyMatchingRegex(
      Iterable<? extends Object> elements, String toStringMatching) {
    toStringMatching = ".*" + toStringMatching + ".*";
    int result = 0;
    for (Object o : elements) {
      if (o.toString().matches(toStringMatching)) {
        ++result;
      }
    }
    return result;
  }

  @Test
  public void testGetSkyframeEvaluatedTargetKeysOmitsCachedTargets() throws Exception {
    scratch.file(
        "java/a/BUILD",
        "java_library(name = 'x', srcs = ['A.java'], deps = ['z', 'w'])",
        "java_library(name = 'y', srcs = ['B.java'], deps = ['z', 'w'])",
        "java_library(name = 'z', srcs = ['C.java'])",
        "java_library(name = 'w', srcs = ['D.java'])");

    update("//java/a:x");
    Set<?> oldAnalyzedTargets = getSkyframeEvaluatedTargetKeys();
    assertThat(oldAnalyzedTargets.size()).isAtLeast(2); // could be greater due to implicit deps
    assertThat(countObjectsPartiallyMatchingRegex(oldAnalyzedTargets, "//java/a:x")).isEqualTo(1);
    assertThat(countObjectsPartiallyMatchingRegex(oldAnalyzedTargets, "//java/a:y")).isEqualTo(0);
    assertThat(countObjectsPartiallyMatchingRegex(oldAnalyzedTargets, "//java/a:z")).isEqualTo(1);
    assertThat(countObjectsPartiallyMatchingRegex(oldAnalyzedTargets, "//java/a:w")).isEqualTo(1);

    // Unless the build is not fully cached, we get notified about newly evaluated targets, as well
    // as cached top-level targets. For the two tests above to work correctly, we need to ensure
    // that getSkyframeEvaluatedTargetKeys() doesn't return these.
    update("//java/a:x", "//java/a:y", "//java/a:z");
    Set<?> newAnalyzedTargets = getSkyframeEvaluatedTargetKeys();
    assertThat(newAnalyzedTargets).hasSize(2);
    assertThat(countObjectsPartiallyMatchingRegex(newAnalyzedTargets, "//java/a:B.java"))
        .isEqualTo(1);
    assertThat(countObjectsPartiallyMatchingRegex(newAnalyzedTargets, "//java/a:y")).isEqualTo(1);
  }

  /** Test options class for testing diff-based analysis cache resetting. */
  public static final class DiffResetOptions extends FragmentOptions {
    public static final OptionDefinition PROBABLY_IRRELEVANT_OPTION =
        OptionsParser.getOptionDefinitionByName(DiffResetOptions.class, "probably_irrelevant");
    public static final OptionDefinition ALSO_IRRELEVANT_OPTION =
        OptionsParser.getOptionDefinitionByName(DiffResetOptions.class, "also_irrelevant");
    public static final PatchTransition CLEAR_IRRELEVANT =
        new PatchTransition() {
          @Override
          public ImmutableSet<Class<? extends FragmentOptions>> requiresOptionFragments() {
            return ImmutableSet.of(DiffResetOptions.class);
          }

          @Override
          public BuildOptions patch(BuildOptionsView options, EventHandler eventHandler) {
            BuildOptionsView cloned = options.clone();
            cloned.get(DiffResetOptions.class).probablyIrrelevantOption = "(cleared)";
            cloned.get(DiffResetOptions.class).alsoIrrelevantOption = "(cleared)";
            return cloned.underlying();
          }
        };

    @Option(
        name = "probably_irrelevant",
        defaultValue = "(unset)",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = {OptionEffectTag.UNKNOWN},
        help = "This option is irrelevant to non-uses_irrelevant targets and is trimmed from them.")
    public String probablyIrrelevantOption;

    @Option(
        name = "also_irrelevant",
        defaultValue = "(unset)",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = {OptionEffectTag.UNKNOWN},
        help = "This option is irrelevant to non-uses_irrelevant targets and is trimmed from them.")
    public String alsoIrrelevantOption;

    @Option(
        name = "definitely_relevant",
        defaultValue = "(unset)",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = {OptionEffectTag.UNKNOWN},
        help = "This option is not trimmed and is used by all targets.")
    public String definitelyRelevantOption;

    @Option(
        name = "also_relevant",
        defaultValue = "(unset)",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = {OptionEffectTag.UNKNOWN},
        help = "This option is not trimmed and is used by all targets.")
    public String alsoRelevantOption;

    @Option(
        name = "host_relevant",
        defaultValue = "(unset)",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = {OptionEffectTag.UNKNOWN},
        help = "This option is not trimmed and is used by all host targets.")
    public String hostRelevantOption;

    @Override
    public DiffResetOptions getExec() {
      DiffResetOptions exec = ((DiffResetOptions) super.getExec());
      exec.definitelyRelevantOption = hostRelevantOption;
      return exec;
    }
  }

  /** Test fragment. */
  @StarlarkBuiltin(name = "test_diff_fragment", doc = "fragment for testing differy fragments")
  @RequiresOptions(options = {DiffResetOptions.class})
  public static final class DiffResetFragment extends Fragment implements StarlarkValue {
    public DiffResetFragment(BuildOptions buildOptions) {}
  }

  private void setupDiffResetTesting() throws Exception {
    ImmutableSet<OptionDefinition> optionsThatCanChange =
        ImmutableSet.of(
            DiffResetOptions.PROBABLY_IRRELEVANT_OPTION, DiffResetOptions.ALSO_IRRELEVANT_OPTION);
    ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder();
    TestRuleClassProvider.addStandardRules(builder);
    builder.addConfigurationFragment(DiffResetFragment.class);
    builder.overrideShouldInvalidateCacheForOptionDiffForTesting(
        (newOptions, changedOption, oldValue, newValue) -> {
          return !optionsThatCanChange.contains(changedOption);
        });
    builder.overrideTrimmingTransitionFactoryForTesting(
        (ruleData) -> {
          if (ruleData.rule().getRuleClassObject().getName().equals("uses_irrelevant")) {
            return NoTransition.INSTANCE;
          }
          return DiffResetOptions.CLEAR_IRRELEVANT;
        });
    useRuleClassProvider(builder.build());
    scratch.file(
        "test/lib.bzl",
        "def _empty_impl(ctx):",
        "  pass",
        "normal_lib = rule(",
        "    implementation = _empty_impl,",
        "    fragments = ['test_diff_fragment'],",
        "    attrs = {",
        "        'deps': attr.label_list(),",
        "        'host_deps': attr.label_list(cfg='exec'),",
        "    },",
        ")",
        "uses_irrelevant = rule(",
        "    implementation = _empty_impl,",
        "    fragments = ['test_diff_fragment'],",
        "    attrs = {",
        "        'deps': attr.label_list(),",
        "        'host_deps': attr.label_list(cfg='exec'),",
        "    },",
        ")");
    update();
  }

  @Test
  public void cacheNotClearedWhenOptionsStaySame() throws Exception {
    setupDiffResetTesting();
    scratch.file(
        "test/BUILD",
        "load(':lib.bzl', 'normal_lib', 'uses_irrelevant')",
        "uses_irrelevant(name='top', deps=[':shared'])",
        "normal_lib(name='shared')");
    useConfiguration("--definitely_relevant=Testing");
    update("//test:top");
    update("//test:top");
    assertNoTargetsVisited();
  }

  @Test
  public void cacheClearedWhenNonAllowedOptionsChange() throws Exception {
    setupDiffResetTesting();
    scratch.file(
        "test/BUILD",
        "load(':lib.bzl', 'normal_lib', 'uses_irrelevant')",
        "uses_irrelevant(name='top', deps=[':shared'])",
        "normal_lib(name='shared')");
    useConfiguration("--definitely_relevant=Test 1");
    update("//test:top");
    useConfiguration("--definitely_relevant=Test 2");
    update("//test:top");
    useConfiguration("--definitely_relevant=Test 1");
    update("//test:top");
    // these targets needed to be reanalyzed even though we built them in this configuration
    // just a moment ago
    assertNumberOfAnalyzedConfigurationsOfTargets(
        ImmutableMap.<String, Integer>builder()
            .put("//test:top", 1)
            .put("//test:shared", 1)
            .build());
  }

  @Test
  public void cacheClearedWhenNonAllowedHostOptionsChange() throws Exception {
    setupDiffResetTesting();
    scratch.file(
        "test/BUILD",
        "load(':lib.bzl', 'normal_lib', 'uses_irrelevant')",
        "uses_irrelevant(name='top', host_deps=[':shared'])",
        "normal_lib(name='shared')");
    useConfiguration("--host_relevant=Test 1");
    update("//test:top");
    useConfiguration("--host_relevant=Test 2");
    update("//test:top");
    useConfiguration("--host_relevant=Test 1");
    update("//test:top");
    // these targets needed to be reanalyzed even though we built them in this configuration
    // just a moment ago
    assertNumberOfAnalyzedConfigurationsOfTargets(
        ImmutableMap.<String, Integer>builder()
            .put("//test:top", 1)
            .put("//test:shared", 1)
            .build());
  }

  @Test
  public void cacheNotClearedWhenAllowedOptionsChange() throws Exception {
    setupDiffResetTesting();
    scratch.file(
        "test/BUILD",
        "load(':lib.bzl', 'normal_lib', 'uses_irrelevant')",
        "uses_irrelevant(name='top', deps=[':shared'])",
        "normal_lib(name='shared')");
    useConfiguration("--definitely_relevant=Testing", "--probably_irrelevant=Test 1");
    update("//test:top");
    useConfiguration("--definitely_relevant=Testing", "--probably_irrelevant=Test 2");
    update("//test:top");
    // the shared library got to reuse the cached value, while the entry point had to be rebuilt in
    // the new configuration
    assertNumberOfAnalyzedConfigurationsOfTargets(
        ImmutableMap.<String, Integer>builder()
            .put("//test:top", 1)
            .put("//test:shared", 0)
            .build());
    useConfiguration("--definitely_relevant=Testing", "--probably_irrelevant=Test 1");
    update("//test:top");
    // now we're back to the old configuration with no cache clears, so no work needed to be done
    assertNumberOfAnalyzedConfigurationsOfTargets(
        ImmutableMap.<String, Integer>builder()
            .put("//test:top", 0)
            .put("//test:shared", 0)
            .build());
  }

  @Test
  public void cacheClearedWhenRedundantDefinesChange_collapseDuplicateDefinesDisabled()
      throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration("--nocollapse_duplicate_defines", "--define=a=1", "--define=a=2");
    update("//test:top");
    useConfiguration("--nocollapse_duplicate_defines", "--define=a=2");
    update("//test:top");
    assertNumberOfAnalyzedConfigurationsOfTargets(ImmutableMap.of("//test:top", 1));
  }

  @Test
  public void cacheNotClearedWhenRedundantDefinesChange() throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration("--collapse_duplicate_defines", "--define=a=1", "--define=a=2");
    update("//test:top");
    useConfiguration("--collapse_duplicate_defines", "--define=a=2");
    update("//test:top");
    assertNumberOfAnalyzedConfigurationsOfTargets(ImmutableMap.of("//test:top", 0));
  }

  @Test
  public void noCacheClearMessageAfterCleanWithSameOptions() throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration();
    update("//test:top");
    cleanSkyframe();
    eventCollector.clear();
    update("//test:top");
    assertNoEvents();
  }

  @Test
  public void noCacheClearMessageAfterCleanWithDifferentOptions() throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration("--definitely_relevant=before");
    update("//test:top");
    cleanSkyframe();
    useConfiguration("--definitely_relevant=after");
    eventCollector.clear();
    update("//test:top");
    assertNoEvents();
  }

  @Test
  public void noCacheClearMessageAfterDiscardAnalysisCacheThenCleanWithSameOptions()
      throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration("--discard_analysis_cache");
    update("//test:top");
    cleanSkyframe();
    eventCollector.clear();
    update("//test:top");
    assertNoEvents();
  }

  @Test
  public void noCacheClearMessageAfterDiscardAnalysisCacheThenCleanWithChangedOptions()
      throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration("--definitely_relevant=before", "--discard_analysis_cache");
    update("//test:top");
    cleanSkyframe();
    useConfiguration("--definitely_relevant=after", "--discard_analysis_cache");
    eventCollector.clear();
    update("//test:top");
    assertNoEvents();
  }

  @Test
  public void cacheClearMessageAfterDiscardAnalysisCacheBuild() throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration(
        "--max_config_changes_to_show=-1",
        "--probably_irrelevant=yeah",
        "--discard_analysis_cache");
    update("//test:top");
    eventCollector.clear();
    update("//test:top");
    assertContainsEvent("--discard_analysis_cache");
    assertDoesNotContainEvent("Build option");
    assertContainsEvent("discarding analysis cache");
  }

  @Test
  public void noCacheClearMessageAfterNonDiscardAnalysisCacheBuild() throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration("--max_config_changes_to_show=-1", "--discard_analysis_cache");
    update("//test:top");
    useConfiguration("--max_config_changes_to_show=-1");
    update("//test:top");
    eventCollector.clear();
    update("//test:top");
    assertNoEvents();
  }

  @Test
  public void noCacheClearMessageAfterIrrelevantOptionChanges() throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration("--max_config_changes_to_show=-1", "--probably_irrelevant=old");
    update("//test:top");
    useConfiguration("--max_config_changes_to_show=-1", "--probably_irrelevant=new");
    eventCollector.clear();
    update("//test:top");
    assertNoEvents();
  }

  @Test
  public void noCacheClearMessageAfterIrrelevantOptionChangesWithDiffDisabled() throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration("--max_config_changes_to_show=0", "--probably_irrelevant=old");
    update("//test:top");
    useConfiguration("--max_config_changes_to_show=0", "--probably_irrelevant=new");
    eventCollector.clear();
    update("//test:top");
    assertNoEvents();
  }

  @Test
  public void cacheClearMessageAfterChangingCpu() throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration("--max_config_changes_to_show=-1", "--cpu=k8");
    update("//test:top");
    useConfiguration("--max_config_changes_to_show=-1", "--cpu=armeabi-v7a");
    eventCollector.clear();
    update("//test:top");
    assertDoesNotContainEvent("--discard_analysis_cache");
    assertContainsEvent("Build option --cpu has changed, discarding analysis cache");
  }

  @Test
  public void cacheClearMessageAfterSingleRelevantOptionChanges() throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration("--max_config_changes_to_show=-1", "--definitely_relevant=old");
    update("//test:top");
    useConfiguration("--max_config_changes_to_show=-1", "--definitely_relevant=new");
    eventCollector.clear();
    update("//test:top");
    assertDoesNotContainEvent("--discard_analysis_cache");
    assertContainsEvent(
        "Build option --definitely_relevant has changed, discarding analysis cache");
  }

  @Test
  public void cacheClearMessageDoesNotIncludeIrrelevantOptions() throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration(
        "--max_config_changes_to_show=-1",
        "--definitely_relevant=old",
        "--probably_irrelevant=old",
        "--also_irrelevant=old");
    update("//test:top");
    useConfiguration(
        "--max_config_changes_to_show=-1",
        "--definitely_relevant=new",
        "--probably_irrelevant=new",
        "--also_irrelevant=new");
    eventCollector.clear();
    update("//test:top");
    assertDoesNotContainEvent("--discard_analysis_cache");
    assertContainsEvent(
        "Build option --definitely_relevant has changed, discarding analysis cache");
  }

  @Test
  public void cacheClearMessageDoesNotIncludeUnchangedOptions() throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration(
        "--max_config_changes_to_show=-1", "--definitely_relevant=old", "--also_relevant=fixed");
    update("//test:top");
    useConfiguration(
        "--max_config_changes_to_show=-1", "--definitely_relevant=new", "--also_relevant=fixed");
    eventCollector.clear();
    update("//test:top");
    assertDoesNotContainEvent("--discard_analysis_cache");
    assertContainsEvent(
        "Build option --definitely_relevant has changed, discarding analysis cache");
  }

  @Test
  public void cacheClearMessageAfterRelevantOptionChangeWithDiffDisabled() throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration("--max_config_changes_to_show=0", "--definitely_relevant=old");
    update("//test:top");
    useConfiguration("--max_config_changes_to_show=0", "--definitely_relevant=new");
    eventCollector.clear();
    update("//test:top");
    assertDoesNotContainEvent("--discard_analysis_cache");
    assertContainsEvent("Build options have changed, discarding analysis cache");
  }

  @Test
  public void cacheClearMessageAfterTwoRelevantOptionsChange() throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration(
        "--max_config_changes_to_show=-1", "--definitely_relevant=old", "--also_relevant=old");
    update("//test:top");
    useConfiguration(
        "--max_config_changes_to_show=-1", "--definitely_relevant=new", "--also_relevant=new");
    eventCollector.clear();
    update("//test:top");
    assertDoesNotContainEvent("--discard_analysis_cache");
    assertContainsEvent(
        "Build options --also_relevant and --definitely_relevant have changed, "
            + "discarding analysis cache");
  }

  @Test
  public void cacheClearMessageAfterMultipleRelevantOptionsChange() throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration(
        "--max_config_changes_to_show=-1",
        "--definitely_relevant=old",
        "--also_relevant=old",
        "--host_relevant=old");
    update("//test:top");
    useConfiguration(
        "--max_config_changes_to_show=-1",
        "--definitely_relevant=new",
        "--also_relevant=new",
        "--host_relevant=new");
    eventCollector.clear();
    update("//test:top");
    assertDoesNotContainEvent("--discard_analysis_cache");
    assertContainsEvent(
        "Build options --also_relevant, --definitely_relevant, and --host_relevant have changed, "
            + "discarding analysis cache");
  }

  @Test
  public void cacheClearMessageAfterMultipleRelevantOptionsChangeWithDiffLimit() throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration(
        "--max_config_changes_to_show=2",
        "--definitely_relevant=old",
        "--also_relevant=old",
        "--host_relevant=old");
    update("//test:top");
    useConfiguration(
        "--max_config_changes_to_show=2",
        "--definitely_relevant=new",
        "--also_relevant=new",
        "--host_relevant=new");
    eventCollector.clear();
    update("//test:top");
    assertDoesNotContainEvent("--discard_analysis_cache");
    assertContainsEvent(
        "Build options --also_relevant, --definitely_relevant, and 1 more have changed, "
            + "discarding analysis cache");
  }

  @Test
  public void cacheClearMessageAfterMultipleRelevantOptionsChangeWithSingleDiffLimit()
      throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration(
        "--max_config_changes_to_show=1",
        "--definitely_relevant=old",
        "--also_relevant=old",
        "--host_relevant=old");
    update("//test:top");
    useConfiguration(
        "--max_config_changes_to_show=1",
        "--definitely_relevant=new",
        "--also_relevant=new",
        "--host_relevant=new");
    eventCollector.clear();
    update("//test:top");
    assertDoesNotContainEvent("--discard_analysis_cache");
    assertContainsEvent(
        "Build options --also_relevant and 2 more have changed, discarding analysis cache");
  }

  @Test
  public void cacheClearMessageAfterDiscardAnalysisCacheBuildWithRelevantOptionChanges()
      throws Exception {
    setupDiffResetTesting();
    scratch.file("test/BUILD", "load(':lib.bzl', 'normal_lib')", "normal_lib(name='top')");
    useConfiguration(
        "--max_config_changes_to_show=-1", "--discard_analysis_cache", "--definitely_relevant=old");
    update("//test:top");
    useConfiguration(
        "--max_config_changes_to_show=-1", "--discard_analysis_cache", "--definitely_relevant=new");
    eventCollector.clear();
    update("//test:top");
    assertContainsEvent("--discard_analysis_cache");
    assertDoesNotContainEvent("Build option");
    assertContainsEvent("discarding analysis cache");
  }
}
