Create AnalysisTestResultInfo for in-build testing.

The new object is tied to --experimental_analysis_testing_improvements
This object will eventually be responsible for signaling to Bazel that a test success/failure action should be created on behalf of the current target. This change, however, only exposes this object as a new provider.

Progress toward #6237.

RELNOTES: None.
PiperOrigin-RevId: 215601605
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 84c8f6d..d685361 100644
--- a/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java
+++ b/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java
@@ -55,6 +55,7 @@
 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.FakeAnalysisTestResultInfoProvider;
 import com.google.devtools.build.skydoc.fakebuildapi.test.FakeTestingModule;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
@@ -181,7 +182,8 @@
     PlatformBootstrap platformBootstrap = new PlatformBootstrap(new FakePlatformCommon());
     RepositoryBootstrap repositoryBootstrap = new RepositoryBootstrap(new FakeRepositoryModule());
     TestingBootstrap testingBootstrap = new TestingBootstrap(new FakeTestingModule(),
-        new FakeAnalysisFailureInfoProvider());
+        new FakeAnalysisFailureInfoProvider(),
+        new FakeAnalysisTestResultInfoProvider());
 
     topLevelBootstrap.addBindingsToBuilder(envBuilder);
     androidBootstrap.addBindingsToBuilder(envBuilder);
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/test/AnalysisTestResultInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/test/AnalysisTestResultInfo.java
new file mode 100644
index 0000000..9e7c72a
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/analysis/test/AnalysisTestResultInfo.java
@@ -0,0 +1,68 @@
+// 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.AnalysisTestResultInfoApi;
+
+/**
+ * Encapsulates the result of analyis-phase testing. Build targets which return an instance of
+ * this provider signal to the build system that it should generate 'stub' test executable.
+ */
+public class AnalysisTestResultInfo extends Info implements AnalysisTestResultInfoApi {
+
+  /**
+   * Singleton provider instance for {@link AnalysisTestResultInfo}.
+   */
+  public static final TestResultInfoProvider SKYLARK_CONSTRUCTOR =
+      new TestResultInfoProvider();
+
+  private final Boolean success;
+  private final String message;
+
+  public AnalysisTestResultInfo(Boolean success, String message) {
+    super(SKYLARK_CONSTRUCTOR, Location.BUILTIN);
+    this.success = success;
+    this.message = message;
+  }
+
+  @Override
+  public Boolean getSuccess() {
+    return success;
+  }
+
+  @Override
+  public String getMessage() {
+    return message;
+  }
+
+  /**
+   * Provider implementation for {@link AnalysisTestResultInfo}.
+   */
+  public static class TestResultInfoProvider
+      extends BuiltinProvider<AnalysisTestResultInfo> implements AnalysisTestResultInfoProviderApi {
+
+    public TestResultInfoProvider() {
+      super("AnalysisTestResultInfo", AnalysisTestResultInfo.class);
+    }
+
+    @Override
+    public AnalysisTestResultInfoApi testResultInfo(Boolean success, String message) {
+      return new AnalysisTestResultInfo(success, message);
+    }
+  }
+}
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 c85ba53..b0251ce 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
@@ -17,6 +17,7 @@
 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.analysis.test.AnalysisTestResultInfo;
 import com.google.devtools.build.lib.rules.core.CoreRules;
 import com.google.devtools.build.lib.skylarkbuildapi.test.TestingBootstrap;
 
@@ -30,9 +31,11 @@
 
   @Override
   public void init(ConfiguredRuleClassProvider.Builder builder) {
-    builder.addSkylarkBootstrap(new TestingBootstrap(
-        new SkylarkTestingModule(),
-        AnalysisFailureInfo.SKYLARK_CONSTRUCTOR));
+    builder.addSkylarkBootstrap(
+        new TestingBootstrap(
+            new SkylarkTestingModule(),
+            AnalysisFailureInfo.SKYLARK_CONSTRUCTOR,
+            AnalysisTestResultInfo.SKYLARK_CONSTRUCTOR));
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/AnalysisTestResultInfoApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/AnalysisTestResultInfoApi.java
new file mode 100644
index 0000000..344ac96
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/test/AnalysisTestResultInfoApi.java
@@ -0,0 +1,84 @@
+// 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.Param;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkConstructor;
+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 = "AnalysisTestResultInfo",
+    doc = "<b>Experimental. This API is experimental and subject to change at any time</b><p> "
+        + "Encapsulates the result of analyis-phase testing. Build targets which return an "
+        + "instance of this provider signal to the build system that it should generate a "
+        + "'stub' test executable which generates the equivalent test result. Analysis-phase "
+        + "('in-build') test rules <b>must</b> return an instance of this provider, and "
+        + "non-analysis-phase test rules <b>cannot</b> return this provider.",
+    documented = false)
+public interface AnalysisTestResultInfoApi extends SkylarkValue {
+
+  @SkylarkCallable(
+      name = "success",
+      doc = "If true, then the analysis-phase test represented by this target passed. If "
+          + "false, the test failed.",
+      documented = false,
+      structField = true,
+      enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_ANALYSIS_TESTING_IMPROVEMENTS
+  )
+  public Boolean getSuccess();
+
+  @SkylarkCallable(
+      name = "message",
+      doc = "A descriptive message containing information about the test and its success/failure.",
+      documented = false,
+      structField = true,
+      enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_ANALYSIS_TESTING_IMPROVEMENTS
+  )
+  public String getMessage();
+
+  /** Provider class for {@link AnalysisTestResultInfoApi} objects. */
+  @SkylarkModule(name = "Provider", documented = false, doc = "")
+  public interface AnalysisTestResultInfoProviderApi extends ProviderApi {
+
+    @SkylarkCallable(
+        name = "AnalysisTestResultInfo",
+        doc = "The <code>AnalysisTestResultInfo</code> constructor.",
+        parameters = {
+            @Param(
+                name = "success",
+                type = Boolean.class,
+                named = true,
+                doc = "If true, then the analysis-phase test represented by this target should "
+                    + "pass. If false, the test should fail."),
+            @Param(
+                name = "message",
+                type = String.class,
+                named = true,
+                doc = "A descriptive message containing information about the test and its "
+                    + "success/failure.")},
+        selfCall = true,
+        enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_ANALYSIS_TESTING_IMPROVEMENTS)
+    @SkylarkConstructor(objectType = AnalysisTestResultInfoApi.class,
+        receiverNameForDoc = "AnalysisTestResultInfo")
+    public AnalysisTestResultInfoApi testResultInfo(Boolean success, String message);
+  }
+}
\ No newline at end of file
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 a51962a..745df17 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
@@ -17,6 +17,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;
+import com.google.devtools.build.lib.skylarkbuildapi.test.AnalysisTestResultInfoApi.AnalysisTestResultInfoProviderApi;
 
 /**
  * {@link Bootstrap} for skylark objects related to testing.
@@ -25,16 +26,20 @@
 
   private final TestingModuleApi testingModule;
   private final AnalysisFailureInfoProviderApi analysisFailureInfoProvider;
+  private final AnalysisTestResultInfoProviderApi testResultInfoProvider;
 
   public TestingBootstrap(TestingModuleApi testingModule,
-      AnalysisFailureInfoProviderApi analysisFailureInfoProvider) {
+      AnalysisFailureInfoProviderApi analysisFailureInfoProvider,
+      AnalysisTestResultInfoProviderApi testResultInfoProvider) {
     this.testingModule = testingModule;
     this.analysisFailureInfoProvider = analysisFailureInfoProvider;
+    this.testResultInfoProvider = testResultInfoProvider;
   }
 
   @Override
   public void addBindingsToBuilder(ImmutableMap.Builder<String, Object> builder) {
     builder.put("testing", testingModule);
     builder.put("AnalysisFailureInfo", analysisFailureInfoProvider);
+    builder.put("AnalysisTestResultInfo", testResultInfoProvider);
   }
 }
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 a35737a..db2ec31 100644
--- a/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
+++ b/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
@@ -65,6 +65,7 @@
 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.FakeAnalysisTestResultInfoProvider;
 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;
@@ -329,7 +330,8 @@
     PlatformBootstrap platformBootstrap = new PlatformBootstrap(new FakePlatformCommon());
     RepositoryBootstrap repositoryBootstrap = new RepositoryBootstrap(new FakeRepositoryModule());
     TestingBootstrap testingBootstrap = new TestingBootstrap(new FakeTestingModule(),
-        new FakeAnalysisFailureInfoProvider());
+        new FakeAnalysisFailureInfoProvider(),
+        new FakeAnalysisTestResultInfoProvider());
 
     ImmutableMap.Builder<String, Object> envBuilder = ImmutableMap.builder();
 
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/test/FakeAnalysisTestResultInfoProvider.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/test/FakeAnalysisTestResultInfoProvider.java
new file mode 100644
index 0000000..3b3cdce
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/test/FakeAnalysisTestResultInfoProvider.java
@@ -0,0 +1,33 @@
+// 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.AnalysisTestResultInfoApi;
+import com.google.devtools.build.lib.skylarkbuildapi.test.AnalysisTestResultInfoApi.AnalysisTestResultInfoProviderApi;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
+
+/**
+ * Fake implementation of {@link AnalysisTestResultInfoProviderApi}.
+ */
+public class FakeAnalysisTestResultInfoProvider implements AnalysisTestResultInfoProviderApi {
+
+  @Override
+  public AnalysisTestResultInfoApi testResultInfo(Boolean success, String message) {
+    return null;
+  }
+
+  @Override
+  public void repr(SkylarkPrinter printer) {}
+}
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java
index 06eb578..c8734de 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java
@@ -29,6 +29,7 @@
 import com.google.devtools.build.lib.analysis.RunfilesProvider;
 import com.google.devtools.build.lib.analysis.configuredtargets.FileConfiguredTarget;
 import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
+import com.google.devtools.build.lib.analysis.test.AnalysisTestResultInfo;
 import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider;
 import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
 import com.google.devtools.build.lib.cmdline.Label;
@@ -1936,6 +1937,52 @@
         "my_rule(name='r', dep = ':lib')");
   }
 
+  @Test
+  public void testTestResultInfo() throws Exception {
+    setSkylarkSemanticsOptions("--experimental_analysis_testing_improvements=true");
+
+    scratch.file(
+        "test/extension.bzl",
+        "def custom_rule_impl(ctx):",
+        "  return [AnalysisTestResultInfo(success = True, message = 'message contents')]",
+        "",
+        "custom_rule = rule(implementation = custom_rule_impl)");
+
+    scratch.file(
+        "test/BUILD",
+        "load('//test:extension.bzl', 'custom_rule')",
+        "",
+        "custom_rule(name = 'r')");
+
+    ConfiguredTarget target = getConfiguredTarget("//test:r");
+    AnalysisTestResultInfo info =
+        (AnalysisTestResultInfo) target.get(AnalysisTestResultInfo.SKYLARK_CONSTRUCTOR.getKey());
+    assertThat(info.getSuccess()).isTrue();
+    assertThat(info.getMessage()).isEqualTo("message contents");
+  }
+
+  @Test
+  public void testTestResultInfoWithoutFlag() throws Exception {
+    setSkylarkSemanticsOptions("--experimental_analysis_testing_improvements=false");
+
+    scratch.file(
+        "test/extension.bzl",
+        "def custom_rule_impl(ctx):",
+        "  return [AnalysisTestResultInfo(success = True, message = 'message contents')]",
+        "",
+        "custom_rule = rule(implementation = custom_rule_impl)");
+
+    scratch.file(
+        "test/BUILD",
+        "load('//test:extension.bzl', 'custom_rule')",
+        "",
+        "custom_rule(name = 'r')");
+
+    reporter.removeHandler(failFastHandler);
+    getConfiguredTarget("//test:r");
+    assertContainsEvent("'Provider' object is not callable");
+  }
+
   /**
    * Skylark integration test that forces inlining.
    */