Implement darwin test in java_test.

PiperOrigin-RevId: 882593123
Change-Id: I4285d4304e748935c6198d1e9cc98199eb3d200f
diff --git a/java/common/java_semantics.bzl b/java/common/java_semantics.bzl
index 31c0a00..58f957e 100644
--- a/java/common/java_semantics.bzl
+++ b/java/common/java_semantics.bzl
@@ -105,6 +105,8 @@
     compatible_javac_options = _compatible_javac_options,
     LAUNCHER_FLAG_LABEL = Label("@bazel_tools//tools/jdk:launcher_flag_alias"),
     PROGUARD_ALLOWLISTER_LABEL = "@bazel_tools//tools/jdk:proguard_whitelister",
+    TOOLS_TEST_DEFAULT_TEST_TOOLCHAIN_TYPE = "@bazel_tools//tools/test:default_test_toolchain_type",
+    TOOLS_TEST_EMPTY_TOOLCHAIN = "@bazel_tools//tools/test:empty_toolchain",
     check_java_info_opens_exports = _check_java_info_opens_exports,
     DOCS = struct(
         for_attribute = lambda name: _DOCS.ATTRS.get(name, ""),
diff --git a/test/java/common/rules/java_test_tests.bzl b/test/java/common/rules/java_test_tests.bzl
index 5c2001c..bd8e685 100644
--- a/test/java/common/rules/java_test_tests.bzl
+++ b/test/java/common/rules/java_test_tests.bzl
@@ -10,6 +10,8 @@
 load("//java:java_test.bzl", "java_test")
 load("//java/common:java_info.bzl", "JavaInfo")
 load("//java/common:java_semantics.bzl", "semantics")
+load("//test/java/common/testutil:mock_cc_toolchain.bzl", "mock_cc_toolchain")
+load("//test/java/common/testutil:mock_test_toolchain.bzl", "mock_test_toolchains")
 load("//test/java/testutil:helper.bzl", "always_passes")
 load("//test/java/testutil:rules/custom_java_info_rule.bzl", "custom_java_info_rule")
 
@@ -267,6 +269,52 @@
     env.expect.that_target(targets.add_support).action_named("Javac").inputs().contains_at_least(compile_jars.to_list())
     env.expect.that_target(targets.no_add_support).action_named("Javac").inputs().contains_none_of(compile_jars.to_list())
 
+def _test_mac_requires_darwin_for_execution(name):
+    util.helper_target(
+        rule = native.platform,
+        name = name + "/darwin_x86_64",
+        constraint_values = [
+            "@platforms//os:macos",
+            "@platforms//cpu:x86_64",
+        ],
+    )
+
+    util.helper_target(
+        rule = java_test,
+        name = name + "/test",
+        srcs = [name + "/Test.java"],
+        use_launcher = False,
+        use_testrunner = 0,
+    )
+
+    util.helper_target(
+        rule = mock_cc_toolchain,
+        name = name + "/cc_toolchain",
+        cpu = "x86_64",
+        os = "macos",
+    )
+
+    toolchains = [Label(name + "/cc_toolchain")] + mock_test_toolchains(
+        name = name + "/test_toolchain",
+        cpu = "x86_64",
+        os = "macos",
+    )
+
+    analysis_test(
+        name = name,
+        target = name + "/test",
+        config_settings = {
+            "//command_line_option:platforms": [Label(name + "/darwin_x86_64")],
+            "//command_line_option:extra_toolchains": toolchains,
+        },
+        impl = _test_mac_requires_darwin_for_execution_impl,
+    )
+
+def _test_mac_requires_darwin_for_execution_impl(env, target):
+    env.expect.that_target(target).provider(testing.ExecutionInfo).requirements().contains_at_least(
+        {"requires-darwin": ""},
+    )
+
 def java_test_tests(name):
     test_suite(
         name = name,
@@ -278,5 +326,6 @@
             _test_coverage_uses_coverage_runner_for_main,
             _test_stamp_values,
             _test_add_test_support_to_compile_time_deps_flag,
+            _test_mac_requires_darwin_for_execution,
         ],
     )
diff --git a/test/java/common/testutil/BUILD b/test/java/common/testutil/BUILD
new file mode 100644
index 0000000..c2afbb3
--- /dev/null
+++ b/test/java/common/testutil/BUILD
@@ -0,0 +1 @@
+package(default_applicable_licenses = ["@rules_java//:license"])
diff --git a/test/java/common/testutil/mock_cc_toolchain.bzl b/test/java/common/testutil/mock_cc_toolchain.bzl
new file mode 100644
index 0000000..6680938
--- /dev/null
+++ b/test/java/common/testutil/mock_cc_toolchain.bzl
@@ -0,0 +1,56 @@
+"""Fake cc_toolchain for testing arbitrary --platforms/--cpu"""
+
+load("@rules_cc//cc:find_cc_toolchain.bzl", "CC_TOOLCHAIN_TYPE")
+load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
+load("@rules_cc//cc/toolchains:cc_toolchain.bzl", "cc_toolchain")
+load("@rules_cc//cc/toolchains:cc_toolchain_config_info.bzl", "CcToolchainConfigInfo")
+
+def _mock_config_impl(ctx):
+    return [
+        cc_common.create_cc_toolchain_config_info(
+            ctx = ctx,
+            toolchain_identifier = ctx.attr.id,
+            compiler = "nothing",
+            # These are deprecated but are mandatory parameters for older Bazel versions.
+            target_system_name = "deprecated_system_name",
+            target_cpu = "deprecated_cpu",
+            target_libc = "deprecated_libc",
+        ),
+    ]
+
+_mock_config = rule(
+    implementation = _mock_config_impl,
+    attrs = {
+        "id": attr.string(mandatory = True),
+    },
+    provides = [CcToolchainConfigInfo],
+)
+
+def mock_cc_toolchain(*, name, cpu, os, **kwargs):
+    _mock_config(
+        name = name + "_config",
+        id = cpu + "-" + os,
+        **kwargs
+    )
+    cc_toolchain(
+        name = name + "_impl",
+        all_files = ":nothing",
+        as_files = ":nothing",
+        compiler_files = ":nothing",
+        dwp_files = ":nothing",
+        linker_files = ":nothing",
+        objcopy_files = ":nothing",
+        strip_files = ":nothing",
+        toolchain_config = name + "_config",
+        **kwargs
+    )
+    native.toolchain(
+        name = name,
+        toolchain = name + "_impl",
+        toolchain_type = CC_TOOLCHAIN_TYPE,
+        target_compatible_with = [
+            "@platforms//cpu:" + cpu,
+            "@platforms//os:" + os,
+        ],
+        **kwargs
+    )
diff --git a/test/java/common/testutil/mock_test_toolchain.bzl b/test/java/common/testutil/mock_test_toolchain.bzl
new file mode 100644
index 0000000..cf73145
--- /dev/null
+++ b/test/java/common/testutil/mock_test_toolchain.bzl
@@ -0,0 +1,29 @@
+"""Fake test toolchain for testing arbitrary --platforms"""
+
+load("@bazel_features//:features.bzl", "bazel_features")
+load("@rules_testing//lib:util.bzl", "util")
+load("//java/common:java_semantics.bzl", "semantics")
+
+def mock_test_toolchains(name, cpu, os):
+    """Creates and returns a list of mock test toolchains for the given cpu and os if they're required.
+
+    Args:
+        name: The name of the toolchain.
+        cpu: The cpu for toolchain should be compatible with.
+        os: The os the toolchain should be compatible with.
+    Returns:
+        A list of toolchain targets.
+    """
+    if not bazel_features.toolchains.has_default_test_toolchain_type:
+        return []
+    util.helper_target(
+        rule = native.toolchain,
+        name = name,
+        toolchain_type = Label(semantics.TOOLS_TEST_DEFAULT_TEST_TOOLCHAIN_TYPE),
+        toolchain = Label(semantics.TOOLS_TEST_EMPTY_TOOLCHAIN),
+        target_compatible_with = [
+            "@platforms//os:" + os,
+            "@platforms//cpu:" + cpu,
+        ],
+    )
+    return [native.package_relative_label(name)]