github.com/bazelbuild/rules_webtesting@v0.2.0/web/internal/web_test.bzl (about)

     1  # Copyright 2016 Google Inc.
     2  #
     3  # Licensed under the Apache License, Version 2.0 (the "License");
     4  # you may not use this file except in compliance with the License.
     5  # You may obtain a copy of the License at
     6  #
     7  #      http://www.apache.org/licenses/LICENSE-2.0
     8  #
     9  # Unless required by applicable law or agreed to in writing, software
    10  # distributed under the License is distributed on an "AS IS" BASIS,
    11  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  # See the License for the specific language governing permissions and
    13  # limitations under the License.
    14  """Implementation of the web_test bazel rule
    15  
    16  DO NOT load this file. Use "@io_bazel_rules_web//web:web.bzl".
    17  """
    18  
    19  load(":collections.bzl", "maps")
    20  load(":files.bzl", "files")
    21  load(":metadata.bzl", "metadata")
    22  load(":provider.bzl", "WebTestInfo")
    23  load(":runfiles.bzl", "runfiles")
    24  
    25  def _web_test_impl(ctx):
    26      if ctx.attr.browser[WebTestInfo].disabled:
    27          return _generate_noop_test(
    28              ctx,
    29              """The browser configuration you requested is temporarily disabled.
    30  
    31  Disabled browser: %s
    32  
    33  Why was this browser disabled?
    34  %s""" % (ctx.attr.browser.label, ctx.attr.browser[WebTestInfo].disabled),
    35          )
    36  
    37      missing_tags = [
    38          tag
    39          for tag in ctx.attr.browser[WebTestInfo].required_tags
    40          if (tag not in ctx.attr.tags) and (tag != "local" or not ctx.attr.local)
    41      ]
    42  
    43      if missing_tags:
    44          fail("Browser {browser} requires tags {tags} that are missing.".format(
    45              browser = ctx.attr.browser.label,
    46              tags = missing_tags,
    47          ))
    48  
    49      return _generate_default_test(ctx)
    50  
    51  def _generate_noop_test(ctx, reason, status = 0):
    52      """Generates a no-op test.
    53  
    54      Args:
    55          ctx: the ctx object for this rule.
    56          reason: string, a description of why the no-op test is being used.
    57          status: int, the exit code the test should return.
    58  
    59      Returns:
    60          an empty struct for this rule.
    61      """
    62      if status:
    63          success = "fails"
    64      else:
    65          success = "passes"
    66  
    67      metadata.create_file(ctx, output = ctx.outputs.web_test_metadata)
    68  
    69      test = ctx.actions.declare_file(ctx.label.name)
    70      ctx.actions.expand_template(
    71          template = ctx.file.noop_web_test_template,
    72          output = test,
    73          substitutions = {
    74              "%TEMPLATED_success%": success,
    75              "%TEMPLATED_reason%": reason,
    76              "%TEMPLATED_status%": str(status),
    77          },
    78          is_executable = True,
    79      )
    80  
    81      return [DefaultInfo(executable = test)]
    82  
    83  def _generate_default_test(ctx):
    84      patch = ctx.actions.declare_file("%s.tmp.json" % ctx.label.name)
    85      metadata.create_file(
    86          ctx = ctx,
    87          output = patch,
    88          config_label = ctx.attr.config.label,
    89          label = ctx.label,
    90          test_label = ctx.attr.test.label,
    91      )
    92  
    93      metadata.merge_files(
    94          ctx = ctx,
    95          merger = ctx.executable.merger,
    96          output = ctx.outputs.web_test_metadata,
    97          inputs = [
    98              patch,
    99              ctx.attr.config[WebTestInfo].metadata,
   100              ctx.attr.browser[WebTestInfo].metadata,
   101          ],
   102      )
   103  
   104      env_vars = ""
   105      env = maps.clone(ctx.attr.browser[WebTestInfo].environment)
   106      env["WEB_TEST_METADATA"] = files.long_path(ctx, ctx.outputs.web_test_metadata)
   107      for k, v in env.items():
   108          env_vars += "export %s=%s\n" % (k, v)
   109  
   110      test = ctx.actions.declare_file(ctx.label.name)
   111      ctx.actions.expand_template(
   112          template = ctx.file.web_test_template,
   113          output = test,
   114          substitutions = {
   115              "%TEMPLATED_env_vars%": env_vars,
   116              "%TEMPLATED_launcher%": files.long_path(ctx, ctx.executable.launcher),
   117              "%TEMPLATED_metadata%": files.long_path(ctx, ctx.outputs.web_test_metadata),
   118              "%TEMPLATED_test%": files.long_path(ctx, ctx.executable.test),
   119          },
   120          is_executable = True,
   121      )
   122  
   123      return [
   124          DefaultInfo(
   125              executable = test,
   126              runfiles = runfiles.collect(
   127                  ctx = ctx,
   128                  files = [ctx.outputs.web_test_metadata],
   129                  targets = [
   130                      ctx.attr.browser,
   131                      ctx.attr.config,
   132                      ctx.attr.launcher,
   133                      ctx.attr.test,
   134                  ],
   135              ),
   136          ),
   137          testing.ExecutionInfo(env),
   138          testing.TestEnvironment(ctx.attr.browser[WebTestInfo].environment),
   139      ]
   140  
   141  web_test = rule(
   142      attrs = {
   143          "browser": attr.label(
   144              doc = "The browser configuration to use for this test.",
   145              mandatory = True,
   146              providers = [WebTestInfo],
   147          ),
   148          "config": attr.label(
   149              doc = "Additional configuration for this test.",
   150              mandatory = True,
   151              providers = [WebTestInfo],
   152          ),
   153          "data": attr.label_list(
   154              doc = "Additional runtime dependencies for the test.",
   155              allow_files = True,
   156              cfg = "data",
   157          ),
   158          "launcher": attr.label(
   159              doc = "The web test launcher binary.",
   160              cfg = "target",
   161              executable = True,
   162          ),
   163          "merger": attr.label(
   164              doc = "The metadata merger binary.",
   165              default = Label("//go/metadata/main"),
   166              cfg = "host",
   167              executable = True,
   168          ),
   169          "noop_web_test_template": attr.label(
   170              doc =
   171                  "Shell template used to launch test when browser is disabled.",
   172              default = Label("//web/internal:noop_web_test.sh.template"),
   173              allow_single_file = True,
   174          ),
   175          "test": attr.label(
   176              doc = "The test that will be run against the provided browser.",
   177              cfg = "target",
   178              executable = True,
   179              mandatory = True,
   180          ),
   181          "web_test_template": attr.label(
   182              doc = "Shell template used to launch test.",
   183              default = Label("//web/internal:web_test.sh.template"),
   184              allow_single_file = True,
   185          ),
   186      },
   187      doc = "Runs a provided test against a provided browser configuration.",
   188      outputs = {
   189          "web_test_metadata": "%{name}.gen.json",
   190      },
   191      test = True,
   192      implementation = _web_test_impl,
   193  )