diff --git a/rules/test.bzl b/rules/test.bzl index fd7a6d5b3..3774a4b7e 100644 --- a/rules/test.bzl +++ b/rules/test.bzl @@ -1,5 +1,4 @@ -load("@build_bazel_rules_apple//apple/internal/testing:ios_rules.bzl", _ios_internal_ui_test_bundle = "ios_internal_ui_test_bundle", _ios_internal_unit_test_bundle = "ios_internal_unit_test_bundle", _ios_ui_test = "ios_ui_test", _ios_unit_test = "ios_unit_test",) -load("@bazel_skylib//lib:types.bzl", "types") +load("@build_bazel_rules_apple//apple/internal/testing:ios_rules.bzl", _ios_internal_ui_test_bundle = "ios_internal_ui_test_bundle", _ios_internal_unit_test_bundle = "ios_internal_unit_test_bundle", _ios_ui_test = "ios_ui_test", _ios_unit_test = "ios_unit_test") load("//rules:library.bzl", "apple_library") load("//rules:plists.bzl", "process_infoplists") load("//rules/internal:framework_middleman.bzl", "dep_middleman", "framework_middleman") @@ -60,15 +59,12 @@ def _make_named_split(name, split_kwargs, **in_split): def _make_test_suite_splits(factory, name, **in_kwargs): """ Helper function to split up a test for named splits and runners splits - + At the end of the day, we need to able to control how many tests / bundles there are for sharding by class, otherwise it would recompile many times. Finally - you can set the splits to be whatever you want. """ - if "runners" in in_kwargs and "runner" in in_kwargs: - fail("cannot use runner/s attribute in both split and top level kwargs for %s" % test_name) - split_name_to_kwargs = in_kwargs.get("split_name_to_kwargs", {}) splits = {} if split_name_to_kwargs and len(split_name_to_kwargs) > 0: @@ -76,37 +72,65 @@ def _make_test_suite_splits(factory, name, **in_kwargs): test_name = "{}_{}".format(name, suffix) splits[test_name] = factory.make_named_split(name, split_kwargs, **in_kwargs) - runners = in_kwargs.get("runners", []) + runners = in_kwargs.pop("runners", []) if runners and len(runners) > 0: splits_by_runners = {} if len(splits) == 0: splits[name] = in_kwargs for runner in runners: runner_name = runner.rsplit(":", 1)[-1] - for in_test_name, in_split in splits: + for in_test_name, in_split in splits.items(): test_name = "{}_{}".format(in_test_name, runner_name) splits_by_runners[test_name] = factory.make_runner_split(name, runner, **in_split) splits = splits_by_runners return splits def _make_test_suite(factory, name, test_rule, **test_kwargs): - splits = factory.make_test_suite_splits(factory, name, test_kwargs) + splits = factory.make_test_suite_splits(factory, name, **test_kwargs) tests = [] for split_name, split in splits.items(): tests.append(split_name) - test_rule(split_name, split) + factory.make_test(split_name, test_rule, **split) test_suite_visibility = test_kwargs.get("visibility", None) test_suite_tags = test_kwargs.get("tags", []) native.test_suite(name = name, tests = tests, visibility = test_suite_visibility, tags = test_suite_tags) -default_test_suite_factory = struct( +def _make_test(name, test_rule, **kwargs): + """ + Helper to create an individual test + """ + runner = kwargs.pop("runner", None) or _DEFAULT_APPLE_TEST_RUNNER + test_attrs = {k: v for (k, v) in kwargs.items() if k not in _APPLE_BUNDLE_ATTRS} + test_rule( + name = name, + runner = runner, + test_host = kwargs.pop("test_host", None), + deps = kwargs.pop("deps", []), + testonly = kwargs.pop("testonly", True), + **test_attrs + ) + +def _make_tests(factory, name, test_rule, **kwargs): + """ + Main entry point of generating tests" + """ + + # If we have given the reason to generate many tests then do so + if "runners" in kwargs or "split_name_to_kwargs" in kwargs: + factory.make_test_suite(factory, name, test_rule, **kwargs) + else: + factory.make_test(name, test_rule, **kwargs) + +default_test_factory = struct( + make_tests = _make_tests, make_test_suite = _make_test_suite, make_test_suite_splits = _make_test_suite_splits, make_runner_split = _make_runner_split, - make_named_split = _make_named_split + make_named_split = _make_named_split, + make_test = _make_test, ) -def _ios_test(name, bundle_rule, test_rule, test_suite_factory, apple_library, infoplists_by_build_setting = {}, split_name_to_kwargs = {}, internal_test_deps = [], **kwargs): +def _ios_test(name, bundle_rule, test_rule, test_factory, apple_library, infoplists_by_build_setting = {}, split_name_to_kwargs = {}, internal_test_deps = [], **kwargs): """ Builds and packages iOS Unit/UI Tests. @@ -137,10 +161,14 @@ def _ios_test(name, bundle_rule, test_rule, test_suite_factory, apple_library, if ios_test_kwargs.get("test_host", None) == True: ios_test_kwargs["test_host"] = "@build_bazel_rules_ios//rules/test_host_app:iOS-%s-AppHost" % ios_test_kwargs.get("minimum_os_version") - if "runner" in kwargs and "runners" in kwargs: + runners = kwargs.pop("runners", None) + if "runner" in kwargs and (runners and runners != []): fail("cannot specify both runner and runners for %s" % name) - runner = kwargs.pop("runner", kwargs.pop("runners", None)) + if runners: + ios_test_kwargs["runners"] = runners + else: + ios_test_kwargs["runner"] = kwargs.pop("runner", _DEFAULT_APPLE_TEST_RUNNER) # Deduplicate against the test deps if ios_test_kwargs.get("test_host", None): @@ -178,24 +206,10 @@ def _ios_test(name, bundle_rule, test_rule, test_suite_factory, apple_library, deps = [dep_name] + internal_test_deps, **bundle_attrs ) + ios_test_kwargs["deps"] = [test_bundle_name] + test_factory.make_tests(test_factory, name, test_rule, **ios_test_kwargs) - def _make_test(test_name, **kwargs): - runner = kwargs.pop("runner", None) or _DEFAULT_APPLE_TEST_RUNNER - test_attrs = {k: v for (k, v) in kwargs.items() if k not in _APPLE_BUNDLE_ATTRS} - test_rule( - name = test_name, - runner = runner, - deps = [":{}".format(test_bundle_name)], - testonly = testonly, - **test_attrs - ) - - if "runners" in ios_test_kwargs or "split_name_to_kwargs" in ios_test_kwargs: - test_suite_factory.make_test_suite(test_suite_factory, name, _make_test, **ios_test_kwargs) - else: - _make_test(name, **ios_test_kwargs) - -def ios_unit_test(name, apple_library = apple_library, test_suite_factory = default_test_suite_factory, **kwargs): +def ios_unit_test(name, apple_library = apple_library, test_factory = default_test_factory, **kwargs): """ Builds and packages iOS Unit Tests. @@ -204,9 +218,9 @@ def ios_unit_test(name, apple_library = apple_library, test_suite_factory = defa apple_library: The macro used to package sources into a library. **kwargs: Arguments passed to the apple_library and ios_unit_test rules as appropriate. """ - _ios_test(name, _ios_internal_unit_test_bundle, _ios_unit_test, test_suite_factory, apple_library, **kwargs) + _ios_test(name, _ios_internal_unit_test_bundle, _ios_unit_test, test_factory, apple_library, **kwargs) -def ios_ui_test(name, apple_library = apple_library, test_suite_factory = default_test_suite_factory, **kwargs): +def ios_ui_test(name, apple_library = apple_library, test_factory = default_test_factory, **kwargs): """ Builds and packages iOS UI Tests. @@ -217,9 +231,9 @@ def ios_ui_test(name, apple_library = apple_library, test_suite_factory = defaul """ if not kwargs.get("test_host", None): fail("test_host is required for ios_ui_test.") - _ios_test(name, _ios_internal_ui_test_bundle, _ios_ui_test, test_suite_factory, apple_library, **kwargs) + _ios_test(name, _ios_internal_ui_test_bundle, _ios_ui_test, test_factory, apple_library, **kwargs) -def ios_unit_snapshot_test(name, apple_library = apple_library, test_suite_factory = default_test_suite_factory, **kwargs): +def ios_unit_snapshot_test(name, apple_library = apple_library, test_factory = default_test_factory, **kwargs): """ Builds and packages iOS Unit Snapshot Tests. @@ -228,4 +242,4 @@ def ios_unit_snapshot_test(name, apple_library = apple_library, test_suite_facto apple_library: The macro used to package sources into a library. **kwargs: Arguments passed to the apple_library and ios_unit_test rules as appropriate. """ - _ios_test(name, _ios_internal_unit_test_bundle, _ios_unit_test, test_suite_factory, apple_library, internal_test_deps = ["@bazel_tools//tools/cpp/runfiles"], **kwargs) + _ios_test(name, _ios_internal_unit_test_bundle, _ios_unit_test, test_factory, apple_library, internal_test_deps = ["@bazel_tools//tools/cpp/runfiles"], **kwargs)