Remove dependency on discontinued fuchsia/commit_queue module

This copies the "_all_tryjobs" method from fuchsia's module.

Change-Id: I7b728a84c90c91e2415a2aca761972b37bb80525
Reviewed-on: https://flutter-review.googlesource.com/c/recipes/+/59520
Reviewed-by: Christopher Fujino <fujino@google.com>
Commit-Queue: Christopher Fujino <fujino@google.com>
diff --git a/recipe_modules/recipe_testing/__init__.py b/recipe_modules/recipe_testing/__init__.py
index 3589718..3f46e98 100644
--- a/recipe_modules/recipe_testing/__init__.py
+++ b/recipe_modules/recipe_testing/__init__.py
@@ -5,10 +5,10 @@
 DEPS = [
     "flutter/gerrit_util",
     "fuchsia/buildbucket_util",
-    "fuchsia/commit_queue",
     "fuchsia/gerrit",
     "fuchsia/git",
     "fuchsia/gitiles",
+    "fuchsia/luci_config",
     "flutter/subbuild",
     "flutter/swarming_retry",
     "recipe_engine/buildbucket",
diff --git a/recipe_modules/recipe_testing/api.py b/recipe_modules/recipe_testing/api.py
index 9eb7481..56e80eb 100644
--- a/recipe_modules/recipe_testing/api.py
+++ b/recipe_modules/recipe_testing/api.py
@@ -11,10 +11,12 @@
 from google.protobuf import json_format as jsonpb
 from google.protobuf import timestamp_pb2
 
-from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
 from PB.go.chromium.org.luci.buildbucket.proto import (
     builds_service as builds_service_pb2,
+    common as common_pb2,
 )
+from PB.go.chromium.org.luci.cv.api.config.v2 import config as config_pb2
+
 from PB.recipe_modules.flutter.recipe_testing import properties as properties_pb2
 from recipe_engine import recipe_api
 from RECIPE_MODULES.flutter.swarming_retry import api as swarming_retry_api
@@ -365,7 +367,7 @@
     builders = set()
     for project in config.projects:
       project_builders = set(
-          self.m.commit_queue.all_tryjobs(
+          self._all_tryjobs(
               project=project.name,
               include_unrestricted=project.include_unrestricted,
               include_restricted=project.include_restricted,
@@ -549,3 +551,46 @@
       cl_information = \
           self.m.gerrit_util.get_gerrit_cl_details(host, cl_number)
       return cl_information.get('branch')
+
+  def _all_tryjobs(
+      self, project, include_unrestricted, include_restricted, config_name
+  ):
+    cfg = self.m.luci_config.commit_queue(
+        project=project,
+        config_name=config_name or "commit-queue.cfg",
+    )
+    builders = set()
+    config_groups = cfg.config_groups if cfg else []
+    for group in config_groups:
+      triggering_repos = set()
+      for g in group.gerrit:
+        gitiles_host = g.url.replace("-review", "")
+        for p in g.projects:
+          triggering_repos.add(f"{gitiles_host}/{p.name}")
+
+      for builder in group.verifiers.tryjob.builders:
+        # Exclude experimental/optional builders.
+        if builder.experiment_percentage or builder.includable_only:
+          continue
+        # Exclude non-FULL_RUN builders.
+        # mode_allowlist includes "FULL_RUN" by default.
+        if "FULL_RUN" not in (builder.mode_allowlist or ("FULL_RUN",)):
+          continue
+
+        if (not include_unrestricted and
+            builder.result_visibility != config_pb2.COMMENT_LEVEL_RESTRICTED):
+          continue
+        if (not include_restricted and
+            builder.result_visibility == config_pb2.COMMENT_LEVEL_RESTRICTED):
+          continue
+        # If the first location filter is not an exclude rule, then
+        # the builder only runs on an allowlisted (likely very
+        # small) set of file paths and should probably not be
+        # included by default.
+        if (builder.location_filters and
+            not builder.location_filters[0].exclude):
+          continue
+        builders.add(builder.name)
+    builders = sorted(builders)
+    self.m.step.empty("all tryjobs").presentation.logs["tryjobs"] = builders
+    return builders
diff --git a/recipe_modules/recipe_testing/test_api.py b/recipe_modules/recipe_testing/test_api.py
index 113d321..70b2671 100644
--- a/recipe_modules/recipe_testing/test_api.py
+++ b/recipe_modules/recipe_testing/test_api.py
@@ -18,6 +18,260 @@
 ONE_DAY = int(datetime.timedelta(days=1).total_seconds())
 MAX_BUILD_AGE_SECONDS = int(datetime.timedelta(days=28).total_seconds())
 
+DEFAULT_COMMIT_QUEUE_CFGS = {
+    "default":
+        """
+    submit_options: {
+      max_burst: 4
+      burst_delay: {
+        seconds: 480
+      }
+    }
+
+    config_groups: {
+      gerrit: {
+        url: "https://fuchsia-review.googlesource.com"
+        projects: {
+          name: "cobalt"
+          ref_regexp: "refs/heads/.+"
+        }
+      }
+
+      verifiers: {
+        gerrit_cq_ability: {
+          committer_list: "project-fuchsia-committers"
+          dry_run_access_list: "project-fuchsia-tryjob-access"
+        }
+        tryjob: {
+          builders: {
+            name: "fuchsia/try/cobalt-x64-linux"
+          }
+        }
+      }
+    }
+
+    config_groups: {
+      gerrit: {
+        url: "https://fuchsia-review.googlesource.com"
+        projects: {
+          name: "docs"
+          ref_regexp: "refs/heads/.+"
+        }
+      }
+
+      verifiers: {
+        gerrit_cq_ability: {
+          committer_list: "project-fuchsia-committers"
+          dry_run_access_list: "project-fuchsia-tryjob-access"
+        }
+        tryjob: {
+          builders: {
+            name: "fuchsia/try/doc-checker"
+            experiment_percentage: 100
+          }
+          builders: {
+            name: "fuchsia/try/secret-tryjob"
+            result_visibility: COMMENT_LEVEL_RESTRICTED
+          }
+        }
+      }
+    }
+
+    config_groups: {
+      gerrit: {
+        url: "https://fuchsia-review.googlesource.com"
+        projects: {
+          name: "fuchsia"
+          ref_regexp: "refs/heads/.+"
+        }
+      }
+      verifiers: {
+        gerrit_cq_ability: {
+          committer_list: "project-fuchsia-committers"
+          dry_run_access_list: "project-fuchsia-tryjob-access"
+        }
+        tree_status: {
+          url: "https://fuchsia-stem-status.appspot.com"
+        }
+
+        tryjob: {
+          builders: {
+            name: "fuchsia/try/core.arm64-debug"
+          }
+          builders: {
+            name: "fuchsia/try/core.x64-debug"
+          }
+        }
+      }
+    }
+    """,
+    "recipes-only":
+        """
+    submit_options: {
+      max_burst: 4
+      burst_delay: {
+        seconds: 480
+      }
+    }
+
+    config_groups: {
+      gerrit: {
+        url: "https://fuchsia-review.googlesource.com"
+        projects: {
+          name: "cobalt"
+          ref_regexp: "refs/heads/.+"
+        }
+      }
+
+      verifiers: {
+        gerrit_cq_ability: {
+          committer_list: "project-fuchsia-committers"
+          dry_run_access_list: "project-fuchsia-tryjob-access"
+        }
+        tryjob: {
+          builders: {
+            name: "fuchsia/try/recipes"
+          }
+        }
+      }
+    }
+    """,
+    "only-fuchsia-debug":
+        """
+    submit_options: {
+      max_burst: 4
+      burst_delay: {
+        seconds: 480
+      }
+    }
+
+    config_groups: {
+      gerrit: {
+        url: "https://fuchsia-review.googlesource.com"
+        projects: {
+          name: "fuchsia"
+          ref_regexp: "refs/heads/.+"
+        }
+      }
+      verifiers: {
+        gerrit_cq_ability: {
+          committer_list: "project-fuchsia-committers"
+          dry_run_access_list: "project-fuchsia-tryjob-access"
+        }
+        tree_status: {
+          url: "https://fuchsia-stem-status.appspot.com"
+        }
+
+        tryjob: {
+          builders: {
+            name: "fuchsia/try/core.arm64-debug"
+          }
+          builders: {
+            name: "fuchsia/try/core.x64-debug"
+          }
+        }
+      }
+    }
+    """,
+    "includable_only":
+        """
+    submit_options: {
+      max_burst: 4
+      burst_delay: {
+        seconds: 480
+      }
+    }
+
+    config_groups: {
+      gerrit: {
+        url: "https:xx//fuchsia-review.googlesource.com"
+        projects: {
+          name: "fuchsia"
+          ref_regexp: "refs/heads/.+"
+        }
+      }
+      verifiers: {
+        gerrit_cq_ability: {
+          committer_list: "project-fuchsia-committers"
+          dry_run_access_list: "project-fuchsia-tryjob-access"
+        }
+        tree_status: {
+          url: "https://fuchsia-stem-status.appspot.com"
+        }
+
+        tryjob: {
+          builders: {
+            name: "fuchsia/try/core.arm64-debug"
+            includable_only: true
+          }
+        }
+      }
+    }
+    """,
+    "mode_allowlist":
+        """
+    config_groups: {
+      verifiers: {
+        tryjob: {
+          builders: {
+            name: "fuchsia/tricium/tricium"
+            mode_allowlist: "ANALYZER_RUN"
+          }
+        }
+      }
+    }
+    """,
+    "location_filters":
+        """
+    config_groups: {
+      verifiers: {
+        tryjob: {
+          builders: {
+            name: "fuchsia/foo/foo"
+            location_filters {
+              path_regexp: "only-run-on-this-path"
+            }
+          }
+          builders: {
+            name: "fuchsia/foo/bar"
+            location_filters {
+              path_regexp: "don't-run-on-this-path"
+              exclude: true
+            }
+          }
+        }
+      }
+    }
+    """,
+    "empty":
+        """
+    submit_options: {
+      max_burst: 4
+      burst_delay: {
+        seconds: 480
+      }
+    }
+
+    config_groups: {
+      gerrit: {
+        url: "https://fuchsia-review.googlesource.com"
+        projects: {
+          name: "fuchsia"
+          ref_regexp: "refs/heads/.+"
+        }
+      }
+      verifiers: {
+        gerrit_cq_ability: {
+          committer_list: "project-fuchsia-committers"
+          dry_run_access_list: "project-fuchsia-tryjob-access"
+        }
+        tree_status: {
+          url: "https://fuchsia-stem-status.appspot.com"
+        }
+      }
+    }
+    """,
+}
 
 class FlutterRecipeTestingTestApi(recipe_test_api.RecipeTestApi):
 
@@ -188,3 +442,9 @@
         search_results,
         step_name="get builders.get green tryjobs",
     )
+
+  def commit_queue_config_data(
+      self, project, data="default", config_name="commit-queue.cfg"
+  ):
+    data = DEFAULT_COMMIT_QUEUE_CFGS.get(data, data)
+    return self.m.luci_config.mock_config(project, config_name, data)
diff --git a/recipe_modules/recipe_testing/tests/all_try_jobs.expected/include_restricted.json b/recipe_modules/recipe_testing/tests/all_try_jobs.expected/include_restricted.json
new file mode 100644
index 0000000..df7074e
--- /dev/null
+++ b/recipe_modules/recipe_testing/tests/all_try_jobs.expected/include_restricted.json
@@ -0,0 +1,42 @@
+[
+  {
+    "cmd": [],
+    "name": "fetch flutter commit-queue.cfg"
+  },
+  {
+    "cmd": [
+      "prpc",
+      "call",
+      "-format=json",
+      "config.luci.app",
+      "config.service.v2.Configs.GetConfig"
+    ],
+    "infra_step": true,
+    "name": "fetch flutter commit-queue.cfg.get",
+    "stdin": "{\n  \"config_set\": \"projects/flutter\",\n  \"path\": \"commit-queue.cfg\"\n}",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_LINE@proto.output@{@@@",
+      "@@@STEP_LOG_LINE@proto.output@  \"raw_content\": \"CiAgICBzdWJtaXRfb3B0aW9uczogewogICAgICBtYXhfYnVyc3Q6IDQKICAgICAgYnVyc3RfZGVsYXk6IHsKICAgICAgICBzZWNvbmRzOiA0ODAKICAgICAgfQogICAgfQoKICAgIGNvbmZpZ19ncm91cHM6IHsKICAgICAgZ2Vycml0OiB7CiAgICAgICAgdXJsOiAiaHR0cHM6Ly9mdWNoc2lhLXJldmlldy5nb29nbGVzb3VyY2UuY29tIgogICAgICAgIHByb2plY3RzOiB7CiAgICAgICAgICBuYW1lOiAiY29iYWx0IgogICAgICAgICAgcmVmX3JlZ2V4cDogInJlZnMvaGVhZHMvLisiCiAgICAgICAgfQogICAgICB9CgogICAgICB2ZXJpZmllcnM6IHsKICAgICAgICBnZXJyaXRfY3FfYWJpbGl0eTogewogICAgICAgICAgY29tbWl0dGVyX2xpc3Q6ICJwcm9qZWN0LWZ1Y2hzaWEtY29tbWl0dGVycyIKICAgICAgICAgIGRyeV9ydW5fYWNjZXNzX2xpc3Q6ICJwcm9qZWN0LWZ1Y2hzaWEtdHJ5am9iLWFjY2VzcyIKICAgICAgICB9CiAgICAgICAgdHJ5am9iOiB7CiAgICAgICAgICBidWlsZGVyczogewogICAgICAgICAgICBuYW1lOiAiZnVjaHNpYS90cnkvY29iYWx0LXg2NC1saW51eCIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBjb25maWdfZ3JvdXBzOiB7CiAgICAgIGdlcnJpdDogewogICAgICAgIHVybDogImh0dHBzOi8vZnVjaHNpYS1yZXZpZXcuZ29vZ2xlc291cmNlLmNvbSIKICAgICAgICBwcm9qZWN0czogewogICAgICAgICAgbmFtZTogImRvY3MiCiAgICAgICAgICByZWZfcmVnZXhwOiAicmVmcy9oZWFkcy8uKyIKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHZlcmlmaWVyczogewogICAgICAgIGdlcnJpdF9jcV9hYmlsaXR5OiB7CiAgICAgICAgICBjb21taXR0ZXJfbGlzdDogInByb2plY3QtZnVjaHNpYS1jb21taXR0ZXJzIgogICAgICAgICAgZHJ5X3J1bl9hY2Nlc3NfbGlzdDogInByb2plY3QtZnVjaHNpYS10cnlqb2ItYWNjZXNzIgogICAgICAgIH0KICAgICAgICB0cnlqb2I6IHsKICAgICAgICAgIGJ1aWxkZXJzOiB7CiAgICAgICAgICAgIG5hbWU6ICJmdWNoc2lhL3RyeS9kb2MtY2hlY2tlciIKICAgICAgICAgICAgZXhwZXJpbWVudF9wZXJjZW50YWdlOiAxMDAKICAgICAgICAgIH0KICAgICAgICAgIGJ1aWxkZXJzOiB7CiAgICAgICAgICAgIG5hbWU6ICJmdWNoc2lhL3RyeS9zZWNyZXQtdHJ5am9iIgogICAgICAgICAgICByZXN1bHRfdmlzaWJpbGl0eTogQ09NTUVOVF9MRVZFTF9SRVNUUklDVEVECiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgY29uZmlnX2dyb3VwczogewogICAgICBnZXJyaXQ6IHsKICAgICAgICB1cmw6ICJodHRwczovL2Z1Y2hzaWEtcmV2aWV3Lmdvb2dsZXNvdXJjZS5jb20iCiAgICAgICAgcHJvamVjdHM6IHsKICAgICAgICAgIG5hbWU6ICJmdWNoc2lhIgogICAgICAgICAgcmVmX3JlZ2V4cDogInJlZnMvaGVhZHMvLisiCiAgICAgICAgfQogICAgICB9CiAgICAgIHZlcmlmaWVyczogewogICAgICAgIGdlcnJpdF9jcV9hYmlsaXR5OiB7CiAgICAgICAgICBjb21taXR0ZXJfbGlzdDogInByb2plY3QtZnVjaHNpYS1jb21taXR0ZXJzIgogICAgICAgICAgZHJ5X3J1bl9hY2Nlc3NfbGlzdDogInByb2plY3QtZnVjaHNpYS10cnlqb2ItYWNjZXNzIgogICAgICAgIH0KICAgICAgICB0cmVlX3N0YXR1czogewogICAgICAgICAgdXJsOiAiaHR0cHM6Ly9mdWNoc2lhLXN0ZW0tc3RhdHVzLmFwcHNwb3QuY29tIgogICAgICAgIH0KCiAgICAgICAgdHJ5am9iOiB7CiAgICAgICAgICBidWlsZGVyczogewogICAgICAgICAgICBuYW1lOiAiZnVjaHNpYS90cnkvY29yZS5hcm02NC1kZWJ1ZyIKICAgICAgICAgIH0KICAgICAgICAgIGJ1aWxkZXJzOiB7CiAgICAgICAgICAgIG5hbWU6ICJmdWNoc2lhL3RyeS9jb3JlLng2NC1kZWJ1ZyIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIA==\"@@@",
+      "@@@STEP_LOG_LINE@proto.output@}@@@",
+      "@@@STEP_LOG_END@proto.output@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "all tryjobs",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@tryjobs@fuchsia/try/secret-tryjob@@@",
+      "@@@STEP_LOG_END@tryjobs@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "fuchsia/try/secret-tryjob"
+    ],
+    "name": "builders"
+  },
+  {
+    "name": "$result"
+  }
+]
\ No newline at end of file
diff --git a/recipe_modules/recipe_testing/tests/all_try_jobs.expected/include_unrestricted.json b/recipe_modules/recipe_testing/tests/all_try_jobs.expected/include_unrestricted.json
new file mode 100644
index 0000000..5a3bfdb
--- /dev/null
+++ b/recipe_modules/recipe_testing/tests/all_try_jobs.expected/include_unrestricted.json
@@ -0,0 +1,46 @@
+[
+  {
+    "cmd": [],
+    "name": "fetch flutter commit-queue.cfg"
+  },
+  {
+    "cmd": [
+      "prpc",
+      "call",
+      "-format=json",
+      "config.luci.app",
+      "config.service.v2.Configs.GetConfig"
+    ],
+    "infra_step": true,
+    "name": "fetch flutter commit-queue.cfg.get",
+    "stdin": "{\n  \"config_set\": \"projects/flutter\",\n  \"path\": \"commit-queue.cfg\"\n}",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_LINE@proto.output@{@@@",
+      "@@@STEP_LOG_LINE@proto.output@  \"raw_content\": \"CiAgICBzdWJtaXRfb3B0aW9uczogewogICAgICBtYXhfYnVyc3Q6IDQKICAgICAgYnVyc3RfZGVsYXk6IHsKICAgICAgICBzZWNvbmRzOiA0ODAKICAgICAgfQogICAgfQoKICAgIGNvbmZpZ19ncm91cHM6IHsKICAgICAgZ2Vycml0OiB7CiAgICAgICAgdXJsOiAiaHR0cHM6Ly9mdWNoc2lhLXJldmlldy5nb29nbGVzb3VyY2UuY29tIgogICAgICAgIHByb2plY3RzOiB7CiAgICAgICAgICBuYW1lOiAiY29iYWx0IgogICAgICAgICAgcmVmX3JlZ2V4cDogInJlZnMvaGVhZHMvLisiCiAgICAgICAgfQogICAgICB9CgogICAgICB2ZXJpZmllcnM6IHsKICAgICAgICBnZXJyaXRfY3FfYWJpbGl0eTogewogICAgICAgICAgY29tbWl0dGVyX2xpc3Q6ICJwcm9qZWN0LWZ1Y2hzaWEtY29tbWl0dGVycyIKICAgICAgICAgIGRyeV9ydW5fYWNjZXNzX2xpc3Q6ICJwcm9qZWN0LWZ1Y2hzaWEtdHJ5am9iLWFjY2VzcyIKICAgICAgICB9CiAgICAgICAgdHJ5am9iOiB7CiAgICAgICAgICBidWlsZGVyczogewogICAgICAgICAgICBuYW1lOiAiZnVjaHNpYS90cnkvY29iYWx0LXg2NC1saW51eCIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBjb25maWdfZ3JvdXBzOiB7CiAgICAgIGdlcnJpdDogewogICAgICAgIHVybDogImh0dHBzOi8vZnVjaHNpYS1yZXZpZXcuZ29vZ2xlc291cmNlLmNvbSIKICAgICAgICBwcm9qZWN0czogewogICAgICAgICAgbmFtZTogImRvY3MiCiAgICAgICAgICByZWZfcmVnZXhwOiAicmVmcy9oZWFkcy8uKyIKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHZlcmlmaWVyczogewogICAgICAgIGdlcnJpdF9jcV9hYmlsaXR5OiB7CiAgICAgICAgICBjb21taXR0ZXJfbGlzdDogInByb2plY3QtZnVjaHNpYS1jb21taXR0ZXJzIgogICAgICAgICAgZHJ5X3J1bl9hY2Nlc3NfbGlzdDogInByb2plY3QtZnVjaHNpYS10cnlqb2ItYWNjZXNzIgogICAgICAgIH0KICAgICAgICB0cnlqb2I6IHsKICAgICAgICAgIGJ1aWxkZXJzOiB7CiAgICAgICAgICAgIG5hbWU6ICJmdWNoc2lhL3RyeS9kb2MtY2hlY2tlciIKICAgICAgICAgICAgZXhwZXJpbWVudF9wZXJjZW50YWdlOiAxMDAKICAgICAgICAgIH0KICAgICAgICAgIGJ1aWxkZXJzOiB7CiAgICAgICAgICAgIG5hbWU6ICJmdWNoc2lhL3RyeS9zZWNyZXQtdHJ5am9iIgogICAgICAgICAgICByZXN1bHRfdmlzaWJpbGl0eTogQ09NTUVOVF9MRVZFTF9SRVNUUklDVEVECiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgY29uZmlnX2dyb3VwczogewogICAgICBnZXJyaXQ6IHsKICAgICAgICB1cmw6ICJodHRwczovL2Z1Y2hzaWEtcmV2aWV3Lmdvb2dsZXNvdXJjZS5jb20iCiAgICAgICAgcHJvamVjdHM6IHsKICAgICAgICAgIG5hbWU6ICJmdWNoc2lhIgogICAgICAgICAgcmVmX3JlZ2V4cDogInJlZnMvaGVhZHMvLisiCiAgICAgICAgfQogICAgICB9CiAgICAgIHZlcmlmaWVyczogewogICAgICAgIGdlcnJpdF9jcV9hYmlsaXR5OiB7CiAgICAgICAgICBjb21taXR0ZXJfbGlzdDogInByb2plY3QtZnVjaHNpYS1jb21taXR0ZXJzIgogICAgICAgICAgZHJ5X3J1bl9hY2Nlc3NfbGlzdDogInByb2plY3QtZnVjaHNpYS10cnlqb2ItYWNjZXNzIgogICAgICAgIH0KICAgICAgICB0cmVlX3N0YXR1czogewogICAgICAgICAgdXJsOiAiaHR0cHM6Ly9mdWNoc2lhLXN0ZW0tc3RhdHVzLmFwcHNwb3QuY29tIgogICAgICAgIH0KCiAgICAgICAgdHJ5am9iOiB7CiAgICAgICAgICBidWlsZGVyczogewogICAgICAgICAgICBuYW1lOiAiZnVjaHNpYS90cnkvY29yZS5hcm02NC1kZWJ1ZyIKICAgICAgICAgIH0KICAgICAgICAgIGJ1aWxkZXJzOiB7CiAgICAgICAgICAgIG5hbWU6ICJmdWNoc2lhL3RyeS9jb3JlLng2NC1kZWJ1ZyIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIA==\"@@@",
+      "@@@STEP_LOG_LINE@proto.output@}@@@",
+      "@@@STEP_LOG_END@proto.output@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "all tryjobs",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@tryjobs@fuchsia/try/cobalt-x64-linux@@@",
+      "@@@STEP_LOG_LINE@tryjobs@fuchsia/try/core.arm64-debug@@@",
+      "@@@STEP_LOG_LINE@tryjobs@fuchsia/try/core.x64-debug@@@",
+      "@@@STEP_LOG_END@tryjobs@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "fuchsia/try/cobalt-x64-linux",
+      "fuchsia/try/core.arm64-debug",
+      "fuchsia/try/core.x64-debug"
+    ],
+    "name": "builders"
+  },
+  {
+    "name": "$result"
+  }
+]
\ No newline at end of file
diff --git a/recipe_modules/recipe_testing/tests/all_try_jobs.expected/location_filters.json b/recipe_modules/recipe_testing/tests/all_try_jobs.expected/location_filters.json
new file mode 100644
index 0000000..55bcca9
--- /dev/null
+++ b/recipe_modules/recipe_testing/tests/all_try_jobs.expected/location_filters.json
@@ -0,0 +1,42 @@
+[
+  {
+    "cmd": [],
+    "name": "fetch flutter commit-queue.cfg"
+  },
+  {
+    "cmd": [
+      "prpc",
+      "call",
+      "-format=json",
+      "config.luci.app",
+      "config.service.v2.Configs.GetConfig"
+    ],
+    "infra_step": true,
+    "name": "fetch flutter commit-queue.cfg.get",
+    "stdin": "{\n  \"config_set\": \"projects/flutter\",\n  \"path\": \"commit-queue.cfg\"\n}",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_LINE@proto.output@{@@@",
+      "@@@STEP_LOG_LINE@proto.output@  \"raw_content\": \"CiAgICBjb25maWdfZ3JvdXBzOiB7CiAgICAgIHZlcmlmaWVyczogewogICAgICAgIHRyeWpvYjogewogICAgICAgICAgYnVpbGRlcnM6IHsKICAgICAgICAgICAgbmFtZTogImZ1Y2hzaWEvZm9vL2ZvbyIKICAgICAgICAgICAgbG9jYXRpb25fZmlsdGVycyB7CiAgICAgICAgICAgICAgcGF0aF9yZWdleHA6ICJvbmx5LXJ1bi1vbi10aGlzLXBhdGgiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGJ1aWxkZXJzOiB7CiAgICAgICAgICAgIG5hbWU6ICJmdWNoc2lhL2Zvby9iYXIiCiAgICAgICAgICAgIGxvY2F0aW9uX2ZpbHRlcnMgewogICAgICAgICAgICAgIHBhdGhfcmVnZXhwOiAiZG9uJ3QtcnVuLW9uLXRoaXMtcGF0aCIKICAgICAgICAgICAgICBleGNsdWRlOiB0cnVlCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIA==\"@@@",
+      "@@@STEP_LOG_LINE@proto.output@}@@@",
+      "@@@STEP_LOG_END@proto.output@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "all tryjobs",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@tryjobs@fuchsia/foo/bar@@@",
+      "@@@STEP_LOG_END@tryjobs@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "fuchsia/foo/bar"
+    ],
+    "name": "builders"
+  },
+  {
+    "name": "$result"
+  }
+]
\ No newline at end of file
diff --git a/recipe_modules/recipe_testing/tests/all_try_jobs.expected/mode_allowlist.json b/recipe_modules/recipe_testing/tests/all_try_jobs.expected/mode_allowlist.json
new file mode 100644
index 0000000..7665453
--- /dev/null
+++ b/recipe_modules/recipe_testing/tests/all_try_jobs.expected/mode_allowlist.json
@@ -0,0 +1,39 @@
+[
+  {
+    "cmd": [],
+    "name": "fetch flutter commit-queue.cfg"
+  },
+  {
+    "cmd": [
+      "prpc",
+      "call",
+      "-format=json",
+      "config.luci.app",
+      "config.service.v2.Configs.GetConfig"
+    ],
+    "infra_step": true,
+    "name": "fetch flutter commit-queue.cfg.get",
+    "stdin": "{\n  \"config_set\": \"projects/flutter\",\n  \"path\": \"commit-queue.cfg\"\n}",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_LINE@proto.output@{@@@",
+      "@@@STEP_LOG_LINE@proto.output@  \"raw_content\": \"CiAgICBjb25maWdfZ3JvdXBzOiB7CiAgICAgIHZlcmlmaWVyczogewogICAgICAgIHRyeWpvYjogewogICAgICAgICAgYnVpbGRlcnM6IHsKICAgICAgICAgICAgbmFtZTogImZ1Y2hzaWEvdHJpY2l1bS90cmljaXVtIgogICAgICAgICAgICBtb2RlX2FsbG93bGlzdDogIkFOQUxZWkVSX1JVTiIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIA==\"@@@",
+      "@@@STEP_LOG_LINE@proto.output@}@@@",
+      "@@@STEP_LOG_END@proto.output@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "all tryjobs",
+    "~followup_annotations": [
+      "@@@STEP_LOG_END@tryjobs@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "builders"
+  },
+  {
+    "name": "$result"
+  }
+]
\ No newline at end of file
diff --git a/recipe_modules/recipe_testing/tests/all_try_jobs.py b/recipe_modules/recipe_testing/tests/all_try_jobs.py
new file mode 100644
index 0000000..908d7a3
--- /dev/null
+++ b/recipe_modules/recipe_testing/tests/all_try_jobs.py
@@ -0,0 +1,102 @@
+# Copyright 2024 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+from PB.recipe_modules.flutter.recipe_testing.options import Project
+
+from recipe_engine import post_process
+
+DEPS = [
+    'flutter/recipe_testing',
+    'recipe_engine/properties',
+    'recipe_engine/step',
+]
+
+PROPERTIES = Project
+
+
+def RunSteps(api, project: Project):
+  builders = api.recipe_testing._all_tryjobs(
+      project.name, project.include_unrestricted, project.include_restricted,
+      project.cq_config_name
+  )
+  api.step('builders', builders)
+
+
+def GenTests(api):
+  yield (
+      api.test(
+          'mode_allowlist',
+          api.recipe_testing.commit_queue_config_data(
+              'flutter', data='mode_allowlist'
+          ),
+          api.properties(
+              Project(
+                  name='flutter',
+                  include_restricted=True,
+                  include_unrestricted=True,
+              )
+          ),
+          api.post_process(post_process.StepCommandEquals, 'builders', []),
+      )
+  )
+
+  yield (
+      api.test(
+          'include_restricted',
+          api.recipe_testing.commit_queue_config_data('flutter'),
+          api.properties(
+              Project(
+                  name='flutter',
+                  include_restricted=True,
+                  include_unrestricted=False,
+              )
+          ),
+          api.post_process(
+              post_process.StepCommandEquals, 'builders',
+              ['fuchsia/try/secret-tryjob']
+          ),
+      )
+  )
+
+  yield (
+      api.test(
+          'include_unrestricted',
+          api.recipe_testing.commit_queue_config_data('flutter'),
+          api.properties(
+              Project(
+                  name='flutter',
+                  include_restricted=False,
+                  include_unrestricted=True,
+              )
+          ),
+          api.post_process(
+              post_process.StepCommandEquals, 'builders', [
+                  'fuchsia/try/cobalt-x64-linux',
+                  'fuchsia/try/core.arm64-debug',
+                  'fuchsia/try/core.x64-debug',
+              ]
+          ),
+      )
+  )
+
+  yield (
+      api.test(
+          'location_filters',
+          api.recipe_testing.commit_queue_config_data(
+              'flutter', data='location_filters'
+          ),
+          api.properties(
+              Project(
+                  name='flutter',
+                  include_restricted=True,
+                  include_unrestricted=True,
+              )
+          ),
+          api.post_process(
+              post_process.StepCommandEquals, 'builders', [
+                  'fuchsia/foo/bar',
+              ]
+          ),
+      )
+  )
diff --git a/recipe_modules/recipe_testing/tests/full.py b/recipe_modules/recipe_testing/tests/full.py
index 2b3d799..dbc9130 100644
--- a/recipe_modules/recipe_testing/tests/full.py
+++ b/recipe_modules/recipe_testing/tests/full.py
@@ -12,7 +12,6 @@
 DEPS = [
     "flutter/recipe_testing",
     "fuchsia/buildbucket_util",
-    "fuchsia/commit_queue",
     "recipe_engine/json",
     "recipe_engine/path",
     "recipe_engine/properties",
@@ -48,7 +47,8 @@
 
   yield (
       api.buildbucket_util.test("recursive_ls") + api.recipe_testing.options() +
-      api.commit_queue.test_data(project, "empty") + test.affected_recipes_data(
+      api.recipe_testing.commit_queue_config_data(project, "empty") +
+      test.affected_recipes_data(
           affected_recipes=[],
           recipe_files=["flutter/flutter.py", "abc.resources/bar.py", "abc.py"],
       )
@@ -56,7 +56,8 @@
 
   yield (
       api.buildbucket_util.test("recipes_cfg") + api.recipe_testing.options() +
-      api.commit_queue.test_data(project, "empty") + test.affected_recipes_data(
+      api.recipe_testing.commit_queue_config_data(project, "empty") +
+      test.affected_recipes_data(
           affected_recipes=[],
           recipe_files=["a.py", "b.py", "c.py", "d.py", "e.py"],
           changed_files=["infra/config/recipes.cfg"],
@@ -65,7 +66,8 @@
 
   yield (
       api.buildbucket_util.test("recipe_proto") + api.recipe_testing.options() +
-      api.commit_queue.test_data(project) + test.affected_recipes_data(
+      api.recipe_testing.commit_queue_config_data(project) +
+      test.affected_recipes_data(
           affected_recipes=[],
           changed_files=["recipe_proto/infra/flutter.proto"],
       )
@@ -73,7 +75,8 @@
 
   yield (
       api.buildbucket_util.test("no_build_old_build_ignored_build") +
-      api.recipe_testing.options() + api.commit_queue.test_data(project) +
+      api.recipe_testing.options() +
+      api.recipe_testing.commit_queue_config_data(project) +
       test.affected_recipes_data(["flutter"]) + test.build_data(
           "fuchsia/try/cobalt-x64-linux",
           "cobalt",
@@ -90,7 +93,7 @@
       api.buildbucket_util.test("excluded") + api.recipe_testing.options([
           api.recipe_testing.project(excluded_buckets=("try",))
       ]) + api.properties(ignored_buckets=["try"]) +
-      api.commit_queue.test_data(project) +
+      api.recipe_testing.commit_queue_config_data(project) +
       test.affected_recipes_data(["flutter"]) + api.post_process(
           post_process.MustRun,
           "excluding 3 builders from bucket flutter/try",
@@ -99,7 +102,8 @@
 
   yield (
       api.buildbucket_util.test("two_pass_one_skip") +
-      api.recipe_testing.options() + api.commit_queue.test_data(project) +
+      api.recipe_testing.options() +
+      api.recipe_testing.commit_queue_config_data(project) +
       test.affected_recipes_data(["fuchsia"]) +
       test.build_data("fuchsia/try/cobalt-x64-linux", "cobalt", skip=True) +
       test.build_data(
@@ -110,7 +114,8 @@
 
   yield (
       api.buildbucket_util.test("fuchsia_recipe_unaffected") +
-      api.recipe_testing.options() + api.commit_queue.test_data(project) +
+      api.recipe_testing.options() +
+      api.recipe_testing.commit_queue_config_data(project) +
       test.affected_recipes_data(["qemu"]) +
       test.build_data("fuchsia/try/cobalt-x64-linux", "cobalt", skip=True) +
       test.build_data("fuchsia/try/core.x64-debug", "fuchsia", skip=True) +
@@ -119,14 +124,14 @@
 
   yield (
       api.buildbucket_util.test("recipes") + api.recipe_testing.options() +
-      api.commit_queue.test_data(project, "recipes-only") +
+      api.recipe_testing.commit_queue_config_data(project, "recipes-only") +
       test.affected_recipes_data(["recipes"]) +
       test.build_data("fuchsia/try/recipes", "recipes")
   )
 
   yield (
       api.buildbucket_util.test("with_buildbucket") +
-      api.commit_queue.test_data(project) +
+      api.recipe_testing.commit_queue_config_data(project) +
       test.affected_recipes_data(["fuchsia"]) + test.build_data(
           "fuchsia/try/cobalt-x64-linux",
           "cobalt",
@@ -160,7 +165,7 @@
 
   yield (
       api.buildbucket_util.test("recipes_with_buildbucket") +
-      api.commit_queue.test_data(project, "recipes-only") +
+      api.recipe_testing.commit_queue_config_data(project, "recipes-only") +
       test.affected_recipes_data(["recipes"]) +
       test.build_data("fuchsia/try/recipes", "recipes", using_led=False) +
       api.recipe_testing.options(use_buildbucket=True)
@@ -168,7 +173,7 @@
 
   yield (
       api.buildbucket_util.test("no_latest_cl") + api.recipe_testing.options() +
-      api.commit_queue.test_data(project) +
+      api.recipe_testing.commit_queue_config_data(project) +
       test.affected_recipes_data(["fuchsia"]) +
       test.build_data("fuchsia/try/core.x64-debug", "fuchsia", cl_cached=True) +
       test.build_data(
diff --git a/recipes/recipes.py b/recipes/recipes.py
index 3843efd..47a5f85 100755
--- a/recipes/recipes.py
+++ b/recipes/recipes.py
@@ -122,7 +122,7 @@
 def GenTests(api):
   yield (
       api.test('ci') + api.properties(unittest_only=False) +
-      api.commit_queue.test_data('flutter', COMMIT_QUEUE_CFG) +
+      api.recipe_testing.commit_queue_config_data('flutter', COMMIT_QUEUE_CFG) +
       api.recipe_testing.affected_recipes_data(['none']) + api.recipe_testing
       .build_data('flutter/try/flutter-foo', 'flutter', skip=True) +
       api.recipe_testing
@@ -135,7 +135,7 @@
   )
   yield (
       api.test('cq_try') + api.properties(unittest_only=False) +
-      api.commit_queue.test_data('flutter', COMMIT_QUEUE_CFG) +
+      api.recipe_testing.commit_queue_config_data('flutter', COMMIT_QUEUE_CFG) +
       api.recipe_testing.affected_recipes_data(['none']) + api.recipe_testing
       .build_data('flutter/try/flutter-foo', 'flutter', skip=True) +
       api.recipe_testing