github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/packetimpact/runner/defs.bzl (about) 1 """Defines rules for packetimpact test targets.""" 2 3 load("//tools:defs.bzl", "go_test") 4 5 def _packetimpact_test_impl(ctx): 6 test_runner = ctx.executable._test_runner 7 bench = ctx.actions.declare_file("%s-bench" % ctx.label.name) 8 bench_content = "\n".join([ 9 "#!/bin/bash", 10 # This test will run part in a distinct user namespace. This can cause 11 # permission problems, because all runfiles may not be owned by the 12 # current user, and no other users will be mapped in that namespace. 13 # Make sure that everything is readable here. 14 "find . -type f -or -type d -exec chmod a+rx {} \\;", 15 "%s %s --testbench_binary %s --num_duts %d $@\n" % ( 16 test_runner.short_path, 17 " ".join(ctx.attr.flags), 18 ctx.files.testbench_binary[0].short_path, 19 ctx.attr.num_duts, 20 ), 21 ]) 22 ctx.actions.write(bench, bench_content, is_executable = True) 23 24 transitive_files = [] 25 if hasattr(ctx.attr._test_runner, "data_runfiles"): 26 transitive_files.append(ctx.attr._test_runner.data_runfiles.files) 27 files = [test_runner] + ctx.files.testbench_binary + ctx.files._posix_server 28 runfiles = ctx.runfiles( 29 files = files, 30 transitive_files = depset(transitive = transitive_files), 31 collect_default = True, 32 collect_data = True, 33 ) 34 return [DefaultInfo(executable = bench, runfiles = runfiles)] 35 36 _packetimpact_test = rule( 37 attrs = { 38 "_test_runner": attr.label( 39 executable = True, 40 cfg = "target", 41 default = ":packetimpact_test", 42 ), 43 "_posix_server": attr.label( 44 cfg = "target", 45 default = "//test/packetimpact/dut:posix_server", 46 ), 47 "testbench_binary": attr.label( 48 cfg = "target", 49 mandatory = True, 50 ), 51 "flags": attr.string_list( 52 mandatory = False, 53 default = [], 54 ), 55 "num_duts": attr.int( 56 mandatory = False, 57 default = 1, 58 ), 59 }, 60 test = True, 61 implementation = _packetimpact_test_impl, 62 ) 63 64 PACKETIMPACT_TAGS = [ 65 "local", 66 "manual", 67 "packetimpact", 68 ] 69 70 def packetimpact_native_test( 71 name, 72 testbench_binary, 73 expect_failure = False, 74 **kwargs): 75 """Add a native packetimpact test. 76 77 Args: 78 name: name of the test 79 testbench_binary: the testbench binary 80 expect_failure: the test must fail 81 **kwargs: all the other args, forwarded to _packetimpact_test 82 """ 83 expect_failure_flag = ["--expect_failure"] if expect_failure else [] 84 _packetimpact_test( 85 name = name + "_native_test", 86 testbench_binary = testbench_binary, 87 flags = ["--native"] + expect_failure_flag, 88 tags = PACKETIMPACT_TAGS, 89 **kwargs 90 ) 91 92 def packetimpact_netstack_test( 93 name, 94 testbench_binary, 95 expect_failure = False, 96 **kwargs): 97 """Add a packetimpact test on netstack. 98 99 Args: 100 name: name of the test 101 testbench_binary: the testbench binary 102 expect_failure: the test must fail 103 **kwargs: all the other args, forwarded to _packetimpact_test 104 """ 105 expect_failure_flag = [] 106 if expect_failure: 107 expect_failure_flag = ["--expect_failure"] 108 _packetimpact_test( 109 name = name + "_netstack_test", 110 testbench_binary = testbench_binary, 111 # Note that a distinct runtime must be provided in the form 112 # --test_arg=--runtime=other when invoking bazel. 113 flags = expect_failure_flag, 114 tags = PACKETIMPACT_TAGS, 115 **kwargs 116 ) 117 118 def packetimpact_go_test(name, expect_native_failure = False, expect_netstack_failure = False, num_duts = 1, **kwargs): 119 """Add packetimpact tests written in go. 120 121 Args: 122 name: name of the test 123 expect_native_failure: the test must fail natively 124 expect_netstack_failure: the test must fail for Netstack 125 num_duts: how many DUTs are needed for the test 126 **kwargs: all the other args, forwarded to packetimpact_native_test and packetimpact_netstack_test 127 """ 128 testbench_binary = name + "_test" 129 packetimpact_native_test( 130 name = name, 131 expect_failure = expect_native_failure, 132 num_duts = num_duts, 133 testbench_binary = testbench_binary, 134 **kwargs 135 ) 136 packetimpact_netstack_test( 137 name = name, 138 expect_failure = expect_netstack_failure, 139 num_duts = num_duts, 140 testbench_binary = testbench_binary, 141 **kwargs 142 ) 143 144 def packetimpact_testbench(name, size = "small", pure = True, **kwargs): 145 """Build packetimpact testbench written in go. 146 147 Args: 148 name: name of the test 149 size: size of the test 150 pure: make a static go binary 151 **kwargs: all the other args, forwarded to go_test 152 """ 153 go_test( 154 name = name + "_test", 155 size = size, 156 pure = pure, 157 nogo = False, # FIXME(gvisor.dev/issue/3374): Not working with all build systems. 158 tags = [ 159 "local", 160 "manual", 161 ], 162 **kwargs 163 ) 164 165 PacketimpactTestInfo = provider( 166 doc = "Provide information for packetimpact tests", 167 fields = [ 168 "name", 169 "timeout", 170 "expect_netstack_failure", 171 "num_duts", 172 ], 173 ) 174 175 ALL_TESTS = [ 176 PacketimpactTestInfo( 177 name = "fin_wait2_timeout", 178 ), 179 PacketimpactTestInfo( 180 name = "ipv4_id_uniqueness", 181 ), 182 PacketimpactTestInfo( 183 name = "udp_discard_mcast_source_addr", 184 ), 185 PacketimpactTestInfo( 186 name = "udp_any_addr_recv_unicast", 187 ), 188 PacketimpactTestInfo( 189 name = "udp_icmp_error_propagation", 190 ), 191 PacketimpactTestInfo( 192 name = "tcp_window_shrink", 193 ), 194 PacketimpactTestInfo( 195 name = "tcp_zero_window_probe", 196 ), 197 PacketimpactTestInfo( 198 name = "tcp_zero_window_probe_retransmit", 199 ), 200 PacketimpactTestInfo( 201 name = "tcp_zero_window_probe_usertimeout", 202 ), 203 PacketimpactTestInfo( 204 name = "tcp_retransmits", 205 ), 206 PacketimpactTestInfo( 207 name = "tcp_outside_the_window", 208 ), 209 PacketimpactTestInfo( 210 name = "tcp_noaccept_close_rst", 211 ), 212 PacketimpactTestInfo( 213 name = "tcp_send_window_sizes_piggyback", 214 ), 215 PacketimpactTestInfo( 216 name = "tcp_unacc_seq_ack", 217 ), 218 PacketimpactTestInfo( 219 name = "tcp_paws_mechanism", 220 # TODO(b/156682000): Fix netstack then remove the line below. 221 expect_netstack_failure = True, 222 ), 223 PacketimpactTestInfo( 224 name = "tcp_user_timeout", 225 ), 226 PacketimpactTestInfo( 227 name = "tcp_zero_receive_window", 228 ), 229 PacketimpactTestInfo( 230 name = "tcp_queue_send_recv_in_syn_sent", 231 ), 232 PacketimpactTestInfo( 233 name = "tcp_synsent_reset", 234 ), 235 PacketimpactTestInfo( 236 name = "tcp_synrcvd_reset", 237 ), 238 PacketimpactTestInfo( 239 name = "tcp_network_unreachable", 240 ), 241 PacketimpactTestInfo( 242 name = "tcp_cork_mss", 243 ), 244 PacketimpactTestInfo( 245 name = "tcp_handshake_window_size", 246 ), 247 PacketimpactTestInfo( 248 name = "tcp_timewait_reset", 249 # TODO(b/168523247): Fix netstack then remove the line below. 250 expect_netstack_failure = True, 251 ), 252 PacketimpactTestInfo( 253 name = "tcp_listen_backlog", 254 ), 255 PacketimpactTestInfo( 256 name = "tcp_syncookie", 257 ), 258 PacketimpactTestInfo( 259 name = "tcp_connect_icmp_error", 260 ), 261 PacketimpactTestInfo( 262 name = "icmpv6_param_problem", 263 ), 264 PacketimpactTestInfo( 265 name = "ipv6_unknown_options_action", 266 ), 267 PacketimpactTestInfo( 268 name = "ipv4_fragment_reassembly", 269 ), 270 PacketimpactTestInfo( 271 name = "ipv6_fragment_reassembly", 272 ), 273 PacketimpactTestInfo( 274 name = "ipv6_fragment_icmp_error", 275 num_duts = 3, 276 ), 277 PacketimpactTestInfo( 278 name = "tcp_linger", 279 ), 280 PacketimpactTestInfo( 281 name = "tcp_rcv_buf_space", 282 ), 283 PacketimpactTestInfo( 284 name = "tcp_rack", 285 expect_netstack_failure = True, 286 ), 287 PacketimpactTestInfo( 288 name = "tcp_info", 289 ), 290 PacketimpactTestInfo( 291 name = "tcp_fin_retransmission", 292 ), 293 PacketimpactTestInfo( 294 name = "generic_dgram_socket_send_recv", 295 timeout = "long", 296 ), 297 ] 298 299 def validate_all_tests(): 300 """ 301 Make sure that ALL_TESTS list is in sync with the rules in BUILD. 302 303 This function is order-dependent, it is intended to be used after 304 all packetimpact_testbench rules and before using ALL_TESTS list 305 at the end of BUILD. 306 """ 307 all_tests_dict = {} # there is no set, using dict to approximate. 308 for test in ALL_TESTS: 309 rule_name = test.name + "_test" 310 all_tests_dict[rule_name] = True 311 if not native.existing_rule(rule_name): 312 fail("%s does not have a packetimpact_testbench rule in BUILD" % test.name) 313 for name in native.existing_rules(): 314 if name.endswith("_test") and name not in all_tests_dict: 315 fail("%s is not declared in ALL_TESTS list in defs.bzl" % name[:-5])