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 )