github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/runner/defs.bzl (about) 1 """Defines a rule for syscall test targets.""" 2 3 load("//tools:defs.bzl", "default_platform", "platforms") 4 5 def _runner_test_impl(ctx): 6 # Generate a runner binary. 7 runner = ctx.actions.declare_file(ctx.label.name) 8 runner_content = "\n".join([ 9 "#!/bin/bash", 10 "set -euf -x -o pipefail", 11 "if [[ -n \"${TEST_UNDECLARED_OUTPUTS_DIR}\" ]]; then", 12 " mkdir -p \"${TEST_UNDECLARED_OUTPUTS_DIR}\"", 13 " chmod a+rwx \"${TEST_UNDECLARED_OUTPUTS_DIR}\"", 14 "fi", 15 "exec %s %s \"$@\" %s\n" % ( 16 ctx.files.runner[0].short_path, 17 " ".join(ctx.attr.runner_args), 18 ctx.files.test[0].short_path, 19 ), 20 ]) 21 ctx.actions.write(runner, runner_content, is_executable = True) 22 23 # Return with all transitive files. 24 runfiles = ctx.runfiles( 25 transitive_files = depset(transitive = [ 26 target.data_runfiles.files 27 for target in (ctx.attr.runner, ctx.attr.test) 28 if hasattr(target, "data_runfiles") 29 ]), 30 files = ctx.files.runner + ctx.files.test, 31 collect_default = True, 32 collect_data = True, 33 ) 34 return [DefaultInfo(executable = runner, runfiles = runfiles)] 35 36 _runner_test = rule( 37 attrs = { 38 "runner": attr.label( 39 default = "//test/runner:runner", 40 ), 41 "test": attr.label( 42 mandatory = True, 43 ), 44 "runner_args": attr.string_list(), 45 "data": attr.label_list( 46 allow_files = True, 47 ), 48 }, 49 test = True, 50 implementation = _runner_test_impl, 51 ) 52 53 def _syscall_test( 54 test, 55 platform, 56 use_tmpfs, 57 tags, 58 debug, 59 network = "none", 60 file_access = "exclusive", 61 overlay = False, 62 add_uds_tree = False, 63 vfs2 = False, 64 fuse = False, 65 **kwargs): 66 # Prepend "runsc" to non-native platform names. 67 full_platform = platform if platform == "native" else "runsc_" + platform 68 69 # Name the test appropriately. 70 name = test.split(":")[1] + "_" + full_platform 71 if file_access == "shared": 72 name += "_shared" 73 if overlay: 74 name += "_overlay" 75 if vfs2: 76 name += "_vfs2" 77 if fuse: 78 name += "_fuse" 79 if network != "none": 80 name += "_" + network + "net" 81 82 # Apply all tags. 83 if tags == None: 84 tags = [] 85 86 # Add the full_platform and file access in a tag to make it easier to run 87 # all the tests on a specific flavor. Use --test_tag_filters=ptrace,file_shared. 88 tags = list(tags) 89 tags += [full_platform, "file_" + file_access] 90 91 # Hash this target into one of 15 buckets. This can be used to 92 # randomly split targets between different workflows. 93 hash15 = hash(native.package_name() + name) % 15 94 tags.append("hash15:" + str(hash15)) 95 tags.append("hash15") 96 97 # Disable off-host networking. 98 tags.append("requires-net:loopback") 99 tags.append("requires-net:ipv4") 100 tags.append("block-network") 101 102 # gotsan makes sense only if tests are running in gVisor. 103 if platform == "native": 104 tags.append("nogotsan") 105 106 container = "container" in tags 107 108 runner_args = [ 109 # Arguments are passed directly to runner binary. 110 "--platform=" + platform, 111 "--network=" + network, 112 "--use-tmpfs=" + str(use_tmpfs), 113 "--file-access=" + file_access, 114 "--overlay=" + str(overlay), 115 "--add-uds-tree=" + str(add_uds_tree), 116 "--vfs2=" + str(vfs2), 117 "--fuse=" + str(fuse), 118 "--strace=" + str(debug), 119 "--debug=" + str(debug), 120 "--container=" + str(container), 121 ] 122 123 # Call the rule above. 124 _runner_test( 125 name = name, 126 test = test, 127 runner_args = runner_args, 128 tags = tags, 129 **kwargs 130 ) 131 132 def syscall_test( 133 test, 134 use_tmpfs = False, 135 add_overlay = False, 136 add_uds_tree = False, 137 add_hostinet = False, 138 vfs2 = True, 139 fuse = False, 140 debug = True, 141 tags = None, 142 **kwargs): 143 """syscall_test is a macro that will create targets for all platforms. 144 145 Args: 146 test: the test target. 147 use_tmpfs: use tmpfs in the defined tests. 148 add_overlay: add an overlay test. 149 add_uds_tree: add a UDS test. 150 add_hostinet: add a hostinet test. 151 vfs2: enable VFS2 support. 152 fuse: enable FUSE support. 153 debug: enable debug output. 154 tags: starting test tags. 155 **kwargs: additional test arguments. 156 """ 157 if not tags: 158 tags = [] 159 160 if vfs2 and not fuse: 161 # Generate a vfs1 plain test. Most testing will now be 162 # biased towards vfs2, with only a single vfs1 case. 163 _syscall_test( 164 test = test, 165 platform = default_platform, 166 use_tmpfs = use_tmpfs, 167 add_uds_tree = add_uds_tree, 168 tags = tags + platforms[default_platform], 169 debug = debug, 170 vfs2 = False, 171 **kwargs 172 ) 173 174 if not fuse: 175 # Generate a native test if fuse is not required. 176 _syscall_test( 177 test = test, 178 platform = "native", 179 use_tmpfs = False, 180 add_uds_tree = add_uds_tree, 181 tags = tags, 182 debug = debug, 183 **kwargs 184 ) 185 186 for (platform, platform_tags) in platforms.items(): 187 _syscall_test( 188 test = test, 189 platform = platform, 190 use_tmpfs = use_tmpfs, 191 add_uds_tree = add_uds_tree, 192 tags = platform_tags + tags, 193 fuse = fuse, 194 vfs2 = vfs2, 195 debug = debug, 196 **kwargs 197 ) 198 199 if add_overlay: 200 _syscall_test( 201 test = test, 202 platform = default_platform, 203 use_tmpfs = use_tmpfs, 204 add_uds_tree = add_uds_tree, 205 tags = platforms[default_platform] + tags, 206 debug = debug, 207 fuse = fuse, 208 vfs2 = vfs2, 209 overlay = True, 210 **kwargs 211 ) 212 if add_hostinet: 213 _syscall_test( 214 test = test, 215 platform = default_platform, 216 use_tmpfs = use_tmpfs, 217 network = "host", 218 add_uds_tree = add_uds_tree, 219 tags = platforms[default_platform] + tags, 220 debug = debug, 221 fuse = fuse, 222 vfs2 = vfs2, 223 **kwargs 224 ) 225 if not use_tmpfs: 226 # Also test shared gofer access. 227 _syscall_test( 228 test = test, 229 platform = default_platform, 230 use_tmpfs = use_tmpfs, 231 add_uds_tree = add_uds_tree, 232 tags = platforms[default_platform] + tags, 233 debug = debug, 234 file_access = "shared", 235 fuse = fuse, 236 vfs2 = vfs2, 237 **kwargs 238 )