Create AnalysisFailureInfo for in-build failure testing.

This new object is tied to a new semantic flag, --experimental_analysis_testing_improvements

Progress toward #6237.

RELNOTES: None.
PiperOrigin-RevId: 215265415
diff --git a/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java b/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java
index b22be9b..84c8f6d 100644
--- a/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java
+++ b/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java
@@ -54,6 +54,7 @@
 import com.google.devtools.build.skydoc.fakebuildapi.java.FakeJavaProtoCommon;
 import com.google.devtools.build.skydoc.fakebuildapi.platform.FakePlatformCommon;
 import com.google.devtools.build.skydoc.fakebuildapi.repository.FakeRepositoryModule;
+import com.google.devtools.build.skydoc.fakebuildapi.test.FakeAnalysisFailureInfoProvider;
 import com.google.devtools.build.skydoc.fakebuildapi.test.FakeTestingModule;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
@@ -179,7 +180,8 @@
             new FakeJavaCommon(), new FakeJavaInfoProvider(), new FakeJavaProtoCommon());
     PlatformBootstrap platformBootstrap = new PlatformBootstrap(new FakePlatformCommon());
     RepositoryBootstrap repositoryBootstrap = new RepositoryBootstrap(new FakeRepositoryModule());
-    TestingBootstrap testingBootstrap = new TestingBootstrap(new FakeTestingModule());
+    TestingBootstrap testingBootstrap = new TestingBootstrap(new FakeTestingModule(),
+        new FakeAnalysisFailureInfoProvider());
 
     topLevelBootstrap.addBindingsToBuilder(envBuilder);
     androidBootstrap.addBindingsToBuilder(envBuilder);
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/test/AnalysisFailure.java b/src/main/java/com/google/devtools/build/lib/analysis/test/AnalysisFailure.java
new file mode 100644
index 0000000..6ab5fb4
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/analysis/test/AnalysisFailure.java
@@ -0,0 +1,50 @@
+// Copyright 2018 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.test;
+
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.skylarkbuildapi.test.AnalysisFailureApi;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
+
+/**
+ * Encapsulates information about an analysis-phase error which would have occurred during a build.
+ */
+public class AnalysisFailure implements AnalysisFailureApi {
+
+  private final Label label;
+  private final String message;
+
+  public AnalysisFailure(
+      Label label,
+      String message) {
+    this.label = label;
+    this.message = message;
+  }
+
+  @Override
+  public Label getLabel() {
+    return label;
+  }
+
+  @Override
+  public String getMessage() {
+    return message;
+  }
+
+  @Override
+  public void repr(SkylarkPrinter printer) {
+    printer.append("<AnalyisFailure object>");
+  }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/test/AnalysisFailureInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/test/AnalysisFailureInfo.java
new file mode 100644
index 0000000..5ee6aea
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/analysis/test/AnalysisFailureInfo.java
@@ -0,0 +1,59 @@
+// Copyright 2018 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.test;
+
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.packages.BuiltinProvider;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.skylarkbuildapi.test.AnalysisFailureInfoApi;
+import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+
+/**
+ * Implementation of {@link AnalysisFailureInfoApi}.
+ *
+ * Encapsulates information about analysis-phase errors which would have occurred during a
+ * build.
+ */
+public class AnalysisFailureInfo extends Info implements AnalysisFailureInfoApi {
+
+  /**
+   * Singleton provider instance for {@link AnalysisFailureInfo}.
+   */
+  public static final AnalysisFailureInfoProvider SKYLARK_CONSTRUCTOR =
+      new AnalysisFailureInfoProvider();
+
+  private final SkylarkNestedSet causes;
+
+  public AnalysisFailureInfo(
+      SkylarkNestedSet causes) {
+    super(SKYLARK_CONSTRUCTOR, Location.BUILTIN);
+    this.causes = causes;
+  }
+
+  @Override
+  public SkylarkNestedSet getCauses() {
+    return causes;
+  }
+
+  /**
+   * Provider implementation for {@link AnalysisFailureInfo}.
+   */
+  public static class AnalysisFailureInfoProvider
+      extends BuiltinProvider<AnalysisFailureInfo> implements AnalysisFailureInfoProviderApi {
+
+    public AnalysisFailureInfoProvider() {
+      super("AnalysisFailureInfo", AnalysisFailureInfo.class);
+    }
+  }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
index 8618b47..814394c 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
@@ -63,6 +63,21 @@
   // <== Add new options here in alphabetic order ==>
 
   @Option(
+      name = "experimental_analysis_testing_improvements",
+      defaultValue = "false",
+      documentationCategory = OptionDocumentationCategory.SKYLARK_SEMANTICS,
+      effectTags = {
+          OptionEffectTag.BUILD_FILE_SEMANTICS,
+          OptionEffectTag.LOADING_AND_ANALYSIS
+      },
+      metadataTags = {
+          OptionMetadataTag.EXPERIMENTAL
+      },
+      help = "If true, enables pieces of experimental Skylark API for analysis-phase testing."
+  )
+  public boolean experimentalAnalysisTestingImprovements;
+
+  @Option(
       name = "experimental_cc_skylark_api_enabled_packages",
       converter = CommaSeparatedOptionListConverter.class,
       defaultValue = "",
@@ -458,6 +473,7 @@
   public SkylarkSemantics toSkylarkSemantics() {
     return SkylarkSemantics.builder()
         // <== Add new options here in alphabetic order ==>
+        .experimentalAnalysisTestingImprovements(experimentalAnalysisTestingImprovements)
         .experimentalCcSkylarkApiEnabledPackages(experimentalCcSkylarkApiEnabledPackages)
         .experimentalEnableRepoMapping(experimentalEnableRepoMapping)
         .experimentalRemapMainRepo(experimentalRemapMainRepo)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestingSupportRules.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestingSupportRules.java
index 8069895..c85ba53 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/test/TestingSupportRules.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/test/TestingSupportRules.java
@@ -16,6 +16,7 @@
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
 import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider.RuleSet;
+import com.google.devtools.build.lib.analysis.test.AnalysisFailureInfo;
 import com.google.devtools.build.lib.rules.core.CoreRules;
 import com.google.devtools.build.lib.skylarkbuildapi.test.TestingBootstrap;
 
@@ -29,7 +30,9 @@
 
   @Override
   public void init(ConfiguredRuleClassProvider.Builder builder) {
-    builder.addSkylarkBootstrap(new TestingBootstrap(new SkylarkTestingModule()));
+    builder.addSkylarkBootstrap(new TestingBootstrap(
+        new SkylarkTestingModule(),
+        AnalysisFailureInfo.SKYLARK_CONSTRUCTOR));
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/AnalysisFailureApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/AnalysisFailureApi.java
new file mode 100644
index 0000000..527cf82
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/AnalysisFailureApi.java
@@ -0,0 +1,56 @@
+// Copyright 2018 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.skylarkbuildapi.test;
+
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
+import com.google.devtools.build.lib.syntax.SkylarkSemantics.FlagIdentifier;
+
+/**
+ * Encapsulates information about an analysis-phase error which would have occurred during a build.
+ */
+@SkylarkModule(
+    name = "AnalysisFailure",
+    doc =
+        "Encapsulates information about an analysis-phase error which would have occurred during "
+            + "a build. In most builds, an analysis-phase error would result in a build failure "
+            + "and the error description would be output to the console. However, if "
+            + "<code>--allow_analysis_failure</code> is set, targets which would otherwise fail in "
+            + "analysis will instead propagate an <code>AnalysisFailureInfo</code> object "
+            + "containing one or more instances of this object.",
+    documented = false)
+public interface AnalysisFailureApi extends SkylarkValue {
+
+  @SkylarkCallable(
+      name = "label",
+      doc = "The label of the target that exhibited an analysis-phase error. This is the label "
+          + "of the target responsible for construction of this object.",
+      documented = false,
+      structField = true,
+      enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_ANALYSIS_TESTING_IMPROVEMENTS
+  )
+  public Label getLabel();
+
+  @SkylarkCallable(
+      name = "message",
+      doc = "A string representation of the analysis-phase error which occurred.",
+      documented = false,
+      structField = true,
+      enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_ANALYSIS_TESTING_IMPROVEMENTS
+  )
+  public String getMessage();
+}
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/AnalysisFailureInfoApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/AnalysisFailureInfoApi.java
new file mode 100644
index 0000000..b626fa2
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/AnalysisFailureInfoApi.java
@@ -0,0 +1,66 @@
+// Copyright 2018 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.skylarkbuildapi.test;
+
+import com.google.devtools.build.lib.skylarkbuildapi.ProviderApi;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
+import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import com.google.devtools.build.lib.syntax.SkylarkSemantics.FlagIdentifier;
+
+/**
+ * Encapsulates information about an analysis-phase error which would have occurred during a build.
+ */
+@SkylarkModule(
+    name = "AnalysisFailureInfo",
+    doc =
+        "Encapsulates information about an analysis-phase error which would have occurred during "
+            + "a build. In most builds, an analysis-phase error would result in a build failure "
+            + "and the error description would be output to the console. However, if "
+            + "<code>--allow_analysis_failure</code> is set, targets which would otherwise fail in "
+            + "analysis will instead propagate an instance of this object (and no other provider "
+            + "instances). "
+            + ""
+            + "<p>Under <code>--allow_analysis_failure</code>, <code>AnalysisFailureInfo</code> "
+            + "objects are automatically re-propagated up a dependency tree using the following "
+            + "logic:<ul>"
+            + ""
+            + "<li>If a target fails but none of its direct dependencies propagated "
+            + "<code>AnalysisFailureInfo</code>, then propagate an instance of this "
+            + "provider containing an <code>AnalysisFailure</code> object describing the "
+            + "failure.</li> "
+            + ""
+            + "<li>If one or more of a target's dependencies propagated "
+            + "<code>AnalysisFailureInfo</code>, then propagate a provider with "
+            + "<code>causes</code> equal to the union of the <code>causes</code> of the "
+            + "dependencies.</li></ul>",
+    documented = false)
+public interface AnalysisFailureInfoApi extends SkylarkValue {
+
+  @SkylarkCallable(
+      name = "causes",
+      doc = "A depset of <code>AnalysisFailure</code> objects describing the failures that "
+          + "occurred in this target or its dependencies.",
+      documented = false,
+      structField = true,
+      enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_ANALYSIS_TESTING_IMPROVEMENTS
+  )
+  public SkylarkNestedSet getCauses();
+
+  /** Provider class for {@link AnalysisFailureInfoApi} objects. */
+  @SkylarkModule(name = "Provider", documented = false, doc = "")
+  public interface AnalysisFailureInfoProviderApi extends ProviderApi {}
+}
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/BUILD b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/BUILD
index ef57962..15c79f7 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/BUILD
@@ -21,6 +21,7 @@
     deps = [
         "//src/main/java/com/google/devtools/build/lib:skylarkinterface",
         "//src/main/java/com/google/devtools/build/lib:syntax",
+        "//src/main/java/com/google/devtools/build/lib/cmdline",
         "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi",
         "//third_party:guava",
         "//third_party:jsr305",
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/TestingBootstrap.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/TestingBootstrap.java
index 40607aa..a51962a 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/TestingBootstrap.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/TestingBootstrap.java
@@ -16,6 +16,7 @@
 
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.skylarkbuildapi.Bootstrap;
+import com.google.devtools.build.lib.skylarkbuildapi.test.AnalysisFailureInfoApi.AnalysisFailureInfoProviderApi;
 
 /**
  * {@link Bootstrap} for skylark objects related to testing.
@@ -23,13 +24,17 @@
 public class TestingBootstrap implements Bootstrap {
 
   private final TestingModuleApi testingModule;
+  private final AnalysisFailureInfoProviderApi analysisFailureInfoProvider;
 
-  public TestingBootstrap(TestingModuleApi testingModule) {
+  public TestingBootstrap(TestingModuleApi testingModule,
+      AnalysisFailureInfoProviderApi analysisFailureInfoProvider) {
     this.testingModule = testingModule;
+    this.analysisFailureInfoProvider = analysisFailureInfoProvider;
   }
 
   @Override
   public void addBindingsToBuilder(ImmutableMap.Builder<String, Object> builder) {
     builder.put("testing", testingModule);
+    builder.put("AnalysisFailureInfo", analysisFailureInfoProvider);
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
index fb1d2df..90192b7 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
@@ -35,6 +35,8 @@
 
   /** Enum where each element represents a skylark semantics flag. */
   public enum FlagIdentifier {
+    EXPERIMENTAL_ANALYSIS_TESTING_IMPROVEMENTS(
+        SkylarkSemantics::experimentalAnalysisTestingImprovements),
     INCOMPATIBLE_DISABLE_OBJC_PROVIDER_RESOURCES(
         SkylarkSemantics::incompatibleDisableObjcProviderResources),
     INCOMPATIBLE_NO_TARGET_OUTPUT_GROUP(
@@ -89,6 +91,8 @@
       AutoValue_SkylarkSemantics.class;
 
   // <== Add new options here in alphabetic order ==>
+  public abstract boolean experimentalAnalysisTestingImprovements();
+
   public abstract List<String> experimentalCcSkylarkApiEnabledPackages();
 
   public abstract boolean experimentalEnableRepoMapping();
@@ -162,6 +166,7 @@
   public static final SkylarkSemantics DEFAULT_SEMANTICS =
       builder()
           // <== Add new options here in alphabetic order ==>
+          .experimentalAnalysisTestingImprovements(false)
           .experimentalCcSkylarkApiEnabledPackages(ImmutableList.of())
           .experimentalEnableRepoMapping(false)
           .experimentalRemapMainRepo(false)
@@ -198,6 +203,8 @@
   public abstract static class Builder {
 
     // <== Add new options here in alphabetic order ==>
+    public abstract Builder experimentalAnalysisTestingImprovements(boolean value);
+
     public abstract Builder experimentalCcSkylarkApiEnabledPackages(List<String> value);
 
     public abstract Builder experimentalEnableRepoMapping(boolean value);
diff --git a/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java b/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
index c3daeb5..a35737a 100644
--- a/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
+++ b/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
@@ -64,6 +64,7 @@
 import com.google.devtools.build.skydoc.fakebuildapi.java.FakeJavaProtoCommon;
 import com.google.devtools.build.skydoc.fakebuildapi.platform.FakePlatformCommon;
 import com.google.devtools.build.skydoc.fakebuildapi.repository.FakeRepositoryModule;
+import com.google.devtools.build.skydoc.fakebuildapi.test.FakeAnalysisFailureInfoProvider;
 import com.google.devtools.build.skydoc.fakebuildapi.test.FakeTestingModule;
 import com.google.devtools.build.skydoc.rendering.MarkdownRenderer;
 import com.google.devtools.build.skydoc.rendering.RuleInfo;
@@ -327,7 +328,8 @@
         new FakeJavaProtoCommon());
     PlatformBootstrap platformBootstrap = new PlatformBootstrap(new FakePlatformCommon());
     RepositoryBootstrap repositoryBootstrap = new RepositoryBootstrap(new FakeRepositoryModule());
-    TestingBootstrap testingBootstrap = new TestingBootstrap(new FakeTestingModule());
+    TestingBootstrap testingBootstrap = new TestingBootstrap(new FakeTestingModule(),
+        new FakeAnalysisFailureInfoProvider());
 
     ImmutableMap.Builder<String, Object> envBuilder = ImmutableMap.builder();
 
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/test/FakeAnalysisFailureInfoProvider.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/test/FakeAnalysisFailureInfoProvider.java
new file mode 100644
index 0000000..4700482
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/test/FakeAnalysisFailureInfoProvider.java
@@ -0,0 +1,27 @@
+// Copyright 2018 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.skydoc.fakebuildapi.test;
+
+import com.google.devtools.build.lib.skylarkbuildapi.test.AnalysisFailureInfoApi.AnalysisFailureInfoProviderApi;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
+
+/**
+ * Fake implementation of {@link AnalysisFailureInfoProviderApi}.
+ */
+public class FakeAnalysisFailureInfoProvider implements AnalysisFailureInfoProviderApi {
+
+  @Override
+  public void repr(SkylarkPrinter printer) {}
+}
diff --git a/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java b/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
index 6ebf71e..0ce528e 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
@@ -118,6 +118,7 @@
   private static SkylarkSemanticsOptions buildRandomOptions(Random rand) throws Exception {
     return parseOptions(
         // <== Add new options here in alphabetic order ==>
+        "--experimental_analysis_testing_improvements=" + rand.nextBoolean(),
         "--experimental_cc_skylark_api_enabled_packages="
             + rand.nextDouble()
             + ","
@@ -159,6 +160,7 @@
   private static SkylarkSemantics buildRandomSemantics(Random rand) {
     return SkylarkSemantics.builder()
         // <== Add new options here in alphabetic order ==>
+        .experimentalAnalysisTestingImprovements(rand.nextBoolean())
         .experimentalCcSkylarkApiEnabledPackages(
             ImmutableList.of(String.valueOf(rand.nextDouble()), String.valueOf(rand.nextDouble())))
         .experimentalEnableRepoMapping(rand.nextBoolean())
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
index 3dae2bc..ae89912 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
@@ -20,7 +20,11 @@
 import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.analysis.test.AnalysisFailure;
+import com.google.devtools.build.lib.analysis.test.AnalysisFailureInfo;
+import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.packages.NativeInfo;
@@ -2268,4 +2272,31 @@
         "First argument of 'load' must be a label and start with either '//', ':', or '@'.",
         "load(':foo.bzl', 'arg')");
   }
+
+  @Test
+  public void testAnalysisFailureInfo() throws Exception {
+    AnalysisFailure cause = new AnalysisFailure(Label.create("test", "test"), "ErrorMessage");
+
+    AnalysisFailureInfo info = new AnalysisFailureInfo(
+        SkylarkNestedSet.of(
+            AnalysisFailure.class, NestedSetBuilder.create(Order.STABLE_ORDER, cause)));
+
+    new SkylarkTest("--experimental_analysis_testing_improvements=true")
+        .update("val", info)
+        .setUp(
+            "causes = val.causes",
+            "label = causes.to_list()[0].label",
+            "message = causes.to_list()[0].message")
+        .testLookup("label", Label.create("test", "test"))
+        .testLookup("message", "ErrorMessage");
+
+    new SkylarkTest()
+        .update("val", info)
+        .testIfErrorContains("'AnalysisFailureInfo' has no field 'causes'", "val.causes");
+
+    new SkylarkTest()
+        .update("val", cause)
+        .testIfErrorContains("'AnalysisFailure' has no field 'message'", "val.message")
+        .testIfErrorContains("'AnalysisFailure' has no field 'label'", "val.label");
+  }
 }