Add implementation of engine_v2/tester for monorepo

Change-Id: If280a381b8cde69f640ff0539c95d942f3c4f7c2
Bug: b/241224027
Reviewed-on: https://flutter-review.googlesource.com/c/recipes/+/36400
Reviewed-by: Ricardo Amador <ricardoamador@google.com>
Reviewed-by: Godofredo Contreras <godofredoc@google.com>
Commit-Queue: William Hesse <whesse@google.com>
diff --git a/recipe_modules/monorepo/test_api.py b/recipe_modules/monorepo/test_api.py
index a3b0d56..e6953d6 100644
--- a/recipe_modules/monorepo/test_api.py
+++ b/recipe_modules/monorepo/test_api.py
@@ -20,11 +20,11 @@
     )
 
   def try_build(self):
-    """An example monorepo ci build"""
+    """An example monorepo try build"""
     return self.m.buildbucket.try_build(
         project='dart',
         bucket='ci.sandbox',
-        builder='host-linux',
+        builder='monorepo_builder_try',
         # Used to construct a Gerrit CL, not a Gitiles commit.
         git_repo='https://dart.googlesource.com/sdk',
         change_number=9425,
diff --git a/recipe_modules/repo_util/examples/full.expected/monorepo_tryjob.json b/recipe_modules/repo_util/examples/full.expected/monorepo_tryjob.json
index 2598caa..d19f805 100644
--- a/recipe_modules/repo_util/examples/full.expected/monorepo_tryjob.json
+++ b/recipe_modules/repo_util/examples/full.expected/monorepo_tryjob.json
@@ -1358,7 +1358,7 @@
       "refs/heads/main"
     ],
     "env": {
-      "DEPOT_TOOLS_REPORT_BUILD": "dart/ci.sandbox/host-linux/8945511751514863184",
+      "DEPOT_TOOLS_REPORT_BUILD": "dart/ci.sandbox/monorepo_builder_try/8945511751514863184",
       "GIT_HTTP_LOW_SPEED_LIMIT": "102400",
       "GIT_HTTP_LOW_SPEED_TIME": "1800"
     },
@@ -1491,7 +1491,7 @@
       "runhooks"
     ],
     "env": {
-      "DEPOT_TOOLS_REPORT_BUILD": "dart/ci.sandbox/host-linux/8945511751514863184"
+      "DEPOT_TOOLS_REPORT_BUILD": "dart/ci.sandbox/monorepo_builder_try/8945511751514863184"
     },
     "env_suffixes": {
       "DEPOT_TOOLS_UPDATE": [
diff --git a/recipes/engine_v2/builder.expected/monorepo_tryjob.json b/recipes/engine_v2/builder.expected/monorepo_tryjob.json
index cfbed40..bc04d90 100644
--- a/recipes/engine_v2/builder.expected/monorepo_tryjob.json
+++ b/recipes/engine_v2/builder.expected/monorepo_tryjob.json
@@ -163,7 +163,7 @@
     "env": {
       "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
       "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
-      "DEPOT_TOOLS_REPORT_BUILD": "dart/ci.sandbox/host-linux/8945511751514863184",
+      "DEPOT_TOOLS_REPORT_BUILD": "dart/ci.sandbox/monorepo_builder_try/8945511751514863184",
       "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
       "ENGINE_PATH": "[CACHE]/builder",
       "GIT_BRANCH": "",
@@ -313,7 +313,7 @@
     "env": {
       "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
       "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
-      "DEPOT_TOOLS_REPORT_BUILD": "dart/ci.sandbox/host-linux/8945511751514863184",
+      "DEPOT_TOOLS_REPORT_BUILD": "dart/ci.sandbox/monorepo_builder_try/8945511751514863184",
       "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
       "ENGINE_PATH": "[CACHE]/builder",
       "GIT_BRANCH": "",
diff --git a/recipes/engine_v2/tester.expected/engine.json b/recipes/engine_v2/tester.expected/engine.json
new file mode 100644
index 0000000..743eb85
--- /dev/null
+++ b/recipes/engine_v2/tester.expected/engine.json
@@ -0,0 +1,275 @@
+[
+  {
+    "cmd": [],
+    "name": "Checkout flutter/flutter"
+  },
+  {
+    "cmd": [
+      "python3",
+      "-u",
+      "RECIPE_MODULE[depot_tools::git]/resources/git_setup.py",
+      "--path",
+      "[CACHE]/builder/flutter",
+      "--url",
+      "https://flutter.googlesource.com/mirrors/flutter"
+    ],
+    "luci_context": {
+      "realm": {
+        "name": "flutter:prod"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/flutter.git setup",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "fetch",
+      "origin",
+      "master",
+      "--recurse-submodules",
+      "--progress",
+      "--tags"
+    ],
+    "cwd": "[CACHE]/builder/flutter",
+    "env": {
+      "PATH": "RECIPE_REPO[depot_tools]:<PATH>"
+    },
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "flutter:prod"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/flutter.git fetch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "checkout",
+      "-f",
+      "FETCH_HEAD"
+    ],
+    "cwd": "[CACHE]/builder/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "flutter:prod"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/flutter.git checkout",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[CACHE]/builder/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "flutter:prod"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/flutter.read revision",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_TEXT@<br/>checked out 'deadbeef'<br/>@@@",
+      "@@@SET_BUILD_PROPERTY@got_revision@\"deadbeef\"@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "clean",
+      "-f",
+      "-d",
+      "-x"
+    ],
+    "cwd": "[CACHE]/builder/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "flutter:prod"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/flutter.git clean",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "submodule",
+      "sync"
+    ],
+    "cwd": "[CACHE]/builder/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "flutter:prod"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/flutter.submodule sync",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "submodule",
+      "update",
+      "--init",
+      "--recursive"
+    ],
+    "cwd": "[CACHE]/builder/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "flutter:prod"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/flutter.submodule update",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "vpython3",
+      "-u",
+      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+      "--json-output",
+      "/path/to/tmp/json",
+      "copy",
+      "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd\n",
+      "[CACHE]/builder/flutter/bin/internal/engine.version"
+    ],
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "flutter:prod"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "update engine version",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@engine.version@abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd@@@",
+      "@@@STEP_LOG_END@engine.version@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "[CACHE]/builder/flutter/bin/flutter",
+      "update-packages"
+    ],
+    "env": {
+      "FLUTTER_STORAGE_BASE_URL": "https://storage.googleapis.com/flutter_archives_v2"
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:prod"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Update packages"
+  },
+  {
+    "cmd": [
+      "[CACHE]/builder/flutter/bin/dart",
+      "[CACHE]/builder/flutter/dev/bots/test.dart"
+    ],
+    "env": {
+      "FLUTTER_STORAGE_BASE_URL": "https://storage.googleapis.com/flutter_archives_v2",
+      "SHARD": "framework_coverage"
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:prod"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Run tests"
+  },
+  {
+    "name": "$result"
+  }
+]
\ No newline at end of file
diff --git a/recipes/engine_v2/tester.expected/monorepo.json b/recipes/engine_v2/tester.expected/monorepo.json
new file mode 100644
index 0000000..6b6c5f7
--- /dev/null
+++ b/recipes/engine_v2/tester.expected/monorepo.json
@@ -0,0 +1,502 @@
+[
+  {
+    "cmd": [],
+    "name": "Checkout flutter/monorepo"
+  },
+  {
+    "cmd": [
+      "python3",
+      "-u",
+      "RECIPE_MODULE[depot_tools::git]/resources/git_setup.py",
+      "--path",
+      "[CACHE]/builder/monorepo",
+      "--url",
+      "https://dart.googlesource.com/monorepo"
+    ],
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/monorepo.git setup",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "fetch",
+      "origin",
+      "--recurse-submodules",
+      "--progress",
+      "--tags"
+    ],
+    "cwd": "[CACHE]/builder/monorepo",
+    "env": {
+      "PATH": "RECIPE_REPO[depot_tools]:<PATH>"
+    },
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/monorepo.git fetch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "checkout",
+      "-f",
+      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    ],
+    "cwd": "[CACHE]/builder/monorepo",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/monorepo.git checkout",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[CACHE]/builder/monorepo",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/monorepo.read revision",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_TEXT@<br/>checked out 'deadbeef'<br/>@@@",
+      "@@@SET_BUILD_PROPERTY@got_revision@\"deadbeef\"@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "clean",
+      "-f",
+      "-d",
+      "-x"
+    ],
+    "cwd": "[CACHE]/builder/monorepo",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/monorepo.git clean",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "submodule",
+      "sync"
+    ],
+    "cwd": "[CACHE]/builder/monorepo",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/monorepo.submodule sync",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "submodule",
+      "update",
+      "--init",
+      "--recursive"
+    ],
+    "cwd": "[CACHE]/builder/monorepo",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/monorepo.submodule update",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "vpython3",
+      "-u",
+      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+      "--json-output",
+      "/path/to/tmp/json",
+      "copy",
+      "[CACHE]/builder/monorepo/commits.json",
+      "/path/to/tmp/"
+    ],
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "get commits from monorepo",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@commits.json@{@@@",
+      "@@@STEP_LOG_LINE@commits.json@  \"engine/src/flutter\": \"57ac2d3d67bde512ed071d0250bfdcb986142ea4\",@@@",
+      "@@@STEP_LOG_LINE@commits.json@  \"engine/src/third_party/dart\": \"355295789e4dee435d6ae2dff3d38dc1d5a9ab9a\",@@@",
+      "@@@STEP_LOG_LINE@commits.json@  \"flutter\": \"523b600efeb7d60b743c1b952201aa969a744791\"@@@",
+      "@@@STEP_LOG_LINE@commits.json@}@@@",
+      "@@@STEP_LOG_END@commits.json@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "Checkout flutter/flutter"
+  },
+  {
+    "cmd": [
+      "python3",
+      "-u",
+      "RECIPE_MODULE[depot_tools::git]/resources/git_setup.py",
+      "--path",
+      "[CACHE]/builder/flutter",
+      "--url",
+      "https://flutter.googlesource.com/mirrors/flutter"
+    ],
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/flutter.git setup",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "fetch",
+      "origin",
+      "--recurse-submodules",
+      "--progress",
+      "--tags"
+    ],
+    "cwd": "[CACHE]/builder/flutter",
+    "env": {
+      "PATH": "RECIPE_REPO[depot_tools]:<PATH>"
+    },
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/flutter.git fetch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "checkout",
+      "-f",
+      "523b600efeb7d60b743c1b952201aa969a744791"
+    ],
+    "cwd": "[CACHE]/builder/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/flutter.git checkout",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[CACHE]/builder/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/flutter.read revision",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_TEXT@<br/>checked out 'deadbeef'<br/>@@@",
+      "@@@SET_BUILD_PROPERTY@got_revision@\"deadbeef\"@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "clean",
+      "-f",
+      "-d",
+      "-x"
+    ],
+    "cwd": "[CACHE]/builder/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/flutter.git clean",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "submodule",
+      "sync"
+    ],
+    "cwd": "[CACHE]/builder/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/flutter.submodule sync",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "submodule",
+      "update",
+      "--init",
+      "--recursive"
+    ],
+    "cwd": "[CACHE]/builder/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Checkout flutter/flutter.submodule update",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "vpython3",
+      "-u",
+      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+      "--json-output",
+      "/path/to/tmp/json",
+      "copy",
+      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n",
+      "[CACHE]/builder/flutter/bin/internal/engine.version"
+    ],
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "update engine version",
+    "~followup_annotations": [
+      "@@@STEP_LOG_LINE@engine.version@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@@@",
+      "@@@STEP_LOG_END@engine.version@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "[CACHE]/builder/flutter/bin/flutter",
+      "update-packages"
+    ],
+    "env": {
+      "FLUTTER_STORAGE_BASE_URL": "https://storage.googleapis.com/flutter_archives_v2/monorepo"
+    },
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Update packages"
+  },
+  {
+    "cmd": [
+      "[CACHE]/builder/flutter/bin/dart",
+      "[CACHE]/builder/flutter/dev/bots/test.dart"
+    ],
+    "env": {
+      "FLUTTER_STORAGE_BASE_URL": "https://storage.googleapis.com/flutter_archives_v2/monorepo",
+      "SHARD": "framework_coverage"
+    },
+    "luci_context": {
+      "realm": {
+        "name": "dart:ci.sandbox"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Run tests"
+  },
+  {
+    "name": "$result"
+  }
+]
\ No newline at end of file
diff --git a/recipes/engine_v2/tester.expected/basic_custom_vars.json b/recipes/engine_v2/tester.expected/monorepo_tryjob.json
similarity index 100%
rename from recipes/engine_v2/tester.expected/basic_custom_vars.json
rename to recipes/engine_v2/tester.expected/monorepo_tryjob.json
diff --git a/recipes/engine_v2/tester.py b/recipes/engine_v2/tester.py
index f5501c3..c57305e 100644
--- a/recipes/engine_v2/tester.py
+++ b/recipes/engine_v2/tester.py
@@ -7,32 +7,110 @@
 This recipe is used to run tests using prebuilt artifacts.
 """
 
-from contextlib import contextmanager
-
-from google.protobuf import struct_pb2
 from PB.recipes.flutter.engine.engine import InputProperties
 from PB.recipes.flutter.engine.engine import EnvProperties
-from PB.go.chromium.org.luci.buildbucket.proto import build as build_pb2
 
 DEPS = [
+    'flutter/monorepo',
+    'flutter/repo_util',
+    'recipe_engine/buildbucket',
+    'recipe_engine/context',
+    'recipe_engine/file',
+    'recipe_engine/json',
+    'recipe_engine/path',
     'recipe_engine/properties',
+    'recipe_engine/step',
 ]
 
 PROPERTIES = InputProperties
 ENV_PROPERTIES = EnvProperties
 
+SAMPLE_MONOREPO_COMMITS = {
+    "engine/src/flutter": "57ac2d3d67bde512ed071d0250bfdcb986142ea4",
+    "engine/src/third_party/dart": "355295789e4dee435d6ae2dff3d38dc1d5a9ab9a",
+    "flutter": "523b600efeb7d60b743c1b952201aa969a744791"
+}
 
-def test(api, test_config):
+
+def get_monorepo_framework(api):
+  monorepo = api.path['cache'].join('builder', 'monorepo')
+  api.repo_util.checkout('monorepo', monorepo)
+  commits = api.file.read_json(
+      'get commits from monorepo',
+      monorepo.join('commits.json'),
+      test_data=SAMPLE_MONOREPO_COMMITS,
+      include_log=True
+  )
+  return commits['flutter']
+
+
+def test(api, builder, flutter, artifact_url):
   """Runs an independent test task."""
-  pass
+  test_config = api.properties.get('build')
+  environment = {
+      'FLUTTER_STORAGE_BASE_URL': artifact_url, 'SHARD': test_config['shard']
+  }
+  with api.context(env=environment):
+    api.step(
+        'Run tests',
+        [flutter.join('bin', 'dart'),
+         flutter.join('dev', 'bots', 'test.dart')]
+    )
+
 
 def RunSteps(api, properties, env_properties):
-  # Test configuration is passed as build property. This is to standardize
-  # the use of BuildBucket and Led APIs in the orchestrator recipe which
-  # triggers the subbuilds.
-  test_config = api.properties.get('build')
-  test(api, test_config)
+  builder = api.path['cache'].join('builder')
+  flutter = builder.join('flutter')
+  if api.monorepo.is_monorepo_try_build:
+    return
+  if api.monorepo.is_monorepo_ci_build:
+    framework_ref = get_monorepo_framework(api)
+    artifact_url = 'https://storage.googleapis.com/flutter_archives_v2/monorepo'
+  else:
+    framework_ref = 'refs/heads/master'
+    artifact_url = 'https://storage.googleapis.com/flutter_archives_v2'
+  engine_version = api.buildbucket.gitiles_commit.id
+  api.repo_util.checkout('flutter', flutter, ref=framework_ref)
+  api.file.write_text(
+      'update engine version',
+      flutter.join('bin', 'internal', 'engine.version'), engine_version + '\n'
+  )
+  environment = {'FLUTTER_STORAGE_BASE_URL': artifact_url}
+  with api.context(env=environment):
+    api.step(
+        'Update packages', [flutter.join('bin', 'flutter'), 'update-packages']
+    )
+  test(api, builder, flutter, artifact_url)
 
 
 def GenTests(api):
-  yield api.test('basic_custom_vars')
+  build = {'shard': 'framework_coverage'}
+  yield api.test(
+      'monorepo',
+      api.properties(build=build, no_goma=True),
+      api.monorepo.ci_build(),
+      api.step_data(
+          'get commits from monorepo',
+          api.file.read_json(SAMPLE_MONOREPO_COMMITS)
+      ),
+  )
+
+  yield api.test(
+      'monorepo_tryjob',
+      api.properties(build=build, no_goma=True),
+      api.monorepo.try_build(),
+  )
+
+  yield api.test(
+      'engine',
+      api.properties(build=build, no_goma=True),
+      api.buildbucket.ci_build(
+          project='flutter',
+          bucket='prod',
+          builder='linux-host',
+          git_repo='https://flutter.googlesource.com/mirrors/engine',
+          git_ref='refs/heads/main',
+          revision='abcd' * 10,
+          build_number=123,
+      ),
+  )