Refactor gerrit recipe

- move chrome binary rename & path stuff into existing helper
- move downloading change into a helper
- add more documentation & api reference links

Change-Id: I58e8878373cfd7bc2632849a01b58c7db41b7339
diff --git a/recipes/recipes/gerrit-web-tests.expected/basic.json b/recipes/recipes/gerrit-web-tests.expected/basic.json
index 868c5fc..32b797b 100644
--- a/recipes/recipes/gerrit-web-tests.expected/basic.json
+++ b/recipes/recipes/gerrit-web-tests.expected/basic.json
@@ -279,7 +279,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "rename to google-chrome"
+    "name": "get chrome.rename to google-chrome",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -362,7 +365,7 @@
   {
     "cmd": [
       "yarn",
-      "install"
+      "setup"
     ],
     "cwd": "[CACHE]/builder/src",
     "env": {
diff --git a/recipes/recipes/gerrit-web-tests.py b/recipes/recipes/gerrit-web-tests.py
index 8e80a6d..3e7f305 100644
--- a/recipes/recipes/gerrit-web-tests.py
+++ b/recipes/recipes/gerrit-web-tests.py
@@ -21,67 +21,46 @@
 # Check out the change and run the tests to verify the change as part of Change
 # Verification (ie. CQ label).
 def RunSteps(api):
-  cl = api.buildbucket.build.input.gerrit_changes[0]
+  # The code for the change will be checked out into a special folder that is
+  # cached between builds.
+  checkout_root = api.path['cache'].join('builder')
+  # This is the name of the subfolder under checkout_root where the change will
+  # be checked out at.
+  checkout_dir = 'src'
 
-  # Remove "-review" part of host URL
-  host = cl.host
-  gs_suffix = '-review.googlesource.com'
-  if host.endswith(gs_suffix):
-    host = '%s.googlesource.com' % host[:-len(gs_suffix)]
+  _downloadGerritChange(api, checkout_root, checkout_dir)
+  env = _downloadChromeAndAddToPath(api)
 
-  gclient_config = api.gclient.make_config()
-  s = gclient_config.solutions.add()
-  s.url = 'https://%s/%s' % (host, cl.project)
-  # This is the name of the subfolder under api.path['cache'].join('builder')
-  # where the repo will be checked out at.
-  s.name = 'src'
-  gclient_config.got_revision_mapping[s.name] = 'got_revision'
-
-  # Check out the code for the change, this is by default cached between builds
-  # for the same builder.
-  with api.context(cwd=api.path['cache'].join('builder')):
-    update_result = api.bot_update.ensure_checkout(
-        gclient_config=gclient_config)
-    api.step.raise_on_failure(update_result)
-
-  # Download Chrome and add to the PATH so that the test runner can launch it
-  # See https://github.com/GoogleChrome/chrome-launcher#launch-options
-  chrome_path = _getChrome(api)
-  env = {
-    'PATH': api.path.pathsep.join([str(chrome_path), '%(PATH)s']),
-  }
-
-  # The chrome-launcher package expects a binary named "google-chrome" rather
-  # than "chrome".
-  # https://github.com/GoogleChrome/chrome-launcher/blob/c753ba083c43a90d98b682bf9ffdfe21680e6208/src/chrome-finder.ts#L133
-  chrome_bin = chrome_path.join('chrome')
-  google_chrome_bin = chrome_path.join('google-chrome')
-  api.step('rename to google-chrome', ['mv', chrome_bin, google_chrome_bin])
-
-  # Now in the checked out code directory run our verification.
-  with api.context(env=env, cwd=api.path['cache'].join('builder').join(s.name)):
-    # Current LTS for Node.js
+  # Now run our verification in the checked out code directory.
+  with api.context(env=env, cwd=checkout_root.join(checkout_dir)):
+    # Current LTS for Node.js. Version must be in CIPD packages:
+    # https://chrome-infra-packages.appspot.com/p/infra/3pp/tools/nodejs/linux-amd64/+/bfm5RWHxZDS1NBdMuNLvXZUq4ULnf_Ho5OzhI3jL_14C
     with api.nodejs(version='18.11.0'):
-      # Named steps to test the change
+      # Named steps to test the change.
       api.step('install yarn', ['npm', 'install', '-g', 'yarn'])
       api.step('install deps', ['yarn', 'setup'])
       api.step('run tests', ['yarn', 'test'])
 
+# Create `checkout_dir` inside the existing `checkout_root` and checks out the
+# change there.
+def _downloadGerritChange(api, checkout_root, checkout_dir):
+  # https://chromium.googlesource.com/chromium/tools/depot_tools/+/refs/heads/main/README.gclient.md
+  gclient_config = api.gclient.make_config()
+  gclient_config.got_revision_mapping[checkout_dir] = 'got_revision'
+  solution = gclient_config.solutions.add()
+  solution.url = 'https://gerrit.googlesource.com/gerrit'
+  solution.name = checkout_dir
 
-# Test the recipe and generate the expect json file.
-def GenTests(api):
-  yield api.test(
-    'basic',
-    # Execute RunSteps with test data
-    api.buildbucket.try_build(
-      project="gerrit",
-      git_repo="https://gerrit.googlesource.com/gerrit",
-    ),
-  )
+  with api.context(cwd=checkout_root):
+    # https://chromium.googlesource.com/chromium/tools/depot_tools/+/refs/heads/main/recipes/recipe_modules/bot_update/api.py#81
+    api.bot_update.ensure_checkout(gclient_config=gclient_config)
 
-# Download and unzip Chrome from a cloud storage bucket.
-# Copied from https://chromium.googlesource.com/infra/infra/+/refs/heads/main/recipes/recipes/gerrit_plugins.py
-def _getChrome(api):
+# Download and unzip Chrome from a cloud storage bucket, then add it to the PATH
+# and rename it for compatibility with our test runner:
+# https://github.com/GoogleChrome/chrome-launcher#launch-options
+# Adapted from:
+# https://chromium.googlesource.com/infra/infra/+/refs/heads/main/recipes/recipes/gerrit_plugins.py
+def _downloadChromeAndAddToPath(api):
   with api.step.nest('get chrome'):
     chrome = api.path.mkdtemp(prefix='chrome')
     gs_bucket = 'chromium-browser-snapshots'
@@ -94,4 +73,26 @@
     api.gsutil.download(gs_bucket, '%s/%s/%s' % (gs_path, version, chrome_zip),
                         chrome)
     api.zip.unzip('unzip chrome', chrome.join(chrome_zip), chrome.join('zip'))
-    return chrome.join('zip', 'chrome-linux')
+    chrome_path = chrome.join('zip', 'chrome-linux')
+
+    # The chrome-launcher package expects a binary named "google-chrome" rather
+    # than "chrome":
+    # https://github.com/GoogleChrome/chrome-launcher/blob/c753ba083c43a90d98b682bf9ffdfe21680e6208/src/chrome-finder.ts#L133
+    chrome_bin = chrome_path.join('chrome')
+    google_chrome_bin = chrome_path.join('google-chrome')
+    api.step('rename to google-chrome', ['mv', chrome_bin, google_chrome_bin])
+    env = {
+      'PATH': api.path.pathsep.join([str(chrome_path), '%(PATH)s']),
+    }
+    return env
+
+# Test the recipe and generate the expect json file.
+def GenTests(api):
+  yield api.test(
+    'basic',
+    # Execute RunSteps with test data
+    api.buildbucket.try_build(
+      project="gerrit",
+      git_repo="https://gerrit.googlesource.com/gerrit",
+    ),
+  )