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