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])