cros_test: Use Simple Chrome's cached version as default when flashing.

This will cause the default version flashed to properly use the
chrome-sdk's cached fallback version. eg: If the LKGM is 9999, but
chrome-sdk falls back to 9998 due to a missing SDK, we'll flash with
9998 instead of failing to flash with 9999.

This also absolutizes the path to `cros` since Chrome bots can't be
assumed to have it on PATH.

BUG=chromium:1057152
TEST=manual unittest (crbug.com/1096664 to automate them)
TEST=ran this on Chrome's Simple Chrome bots: crrev.com/c/1863361/49

Change-Id: I5535f0c7402628ba819a5056a316a87ea642f9c0
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/2251047
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Ben Pastene <bpastene@chromium.org>
Tested-by: Ben Pastene <bpastene@chromium.org>
diff --git a/lib/cros_test.py b/lib/cros_test.py
index ce4cf74..bf929ff 100644
--- a/lib/cros_test.py
+++ b/lib/cros_test.py
@@ -140,23 +140,42 @@
     if not self.flash:
       return
 
-    xbuddy_path = self.xbuddy.format(board=self._device.board)
+    if self.xbuddy:
+      xbuddy_path = self.xbuddy.format(board=self._device.board)
+    else:
+      version = xbuddy.LATEST
+      if path_util.DetermineCheckout().type != path_util.CHECKOUT_TYPE_REPO:
+        # Try flashing to the full version of the board used in the Simple
+        # Chrome SDK if it's present in the cache. Otherwise default to using
+        # latest.
+        cache = self.cache_dir or path_util.GetCacheDir()
+        version = cros_chrome_sdk.SDKFetcher.GetCachedFullVersion(
+            cache, self._device.board) or version
+      # TODO(crbug.com/1057152): Also support flashing a *-full image when
+      # appropriate.
+      xbuddy_path = 'xbuddy://remote/%s-release/%s' % (
+          self._device.board, version)
 
     # Skip the flash if the device is already running the requested version.
     device_version = self._device.remote.version
     _, _, requested_version, _ = xbuddy.XBuddy.InterpretPath(xbuddy_path)
     # Split on the first "-" when comparing versions since xbuddy requires
     # the RX- prefix, but the device may not advertise it.
-    if (requested_version == device_version or
-        requested_version.split('-', 1)[1] == device_version):
-      logging.info(
-          'Skipping the flash. Device running %s when %s was requested',
-          device_version, xbuddy_path)
-      return
+    if xbuddy.LATEST not in requested_version:
+      if (requested_version == device_version or
+          ('-' in requested_version and
+           requested_version.split('-', 1)[1] == device_version)):
+        logging.info(
+            'Skipping the flash. Device running %s when %s was requested',
+            device_version, xbuddy_path)
+        return
 
+    device_name = 'ssh://' + self._device.device
+    if self._device.ssh_port:
+      device_name += ':' + str(self._device.ssh_port)
     cros_build_lib.run(
-        ['cros', 'flash', self._device.device, xbuddy_path,
-         '--board', self._device.board],
+        [os.path.join(constants.CHROMITE_BIN_DIR, 'cros'), 'flash',
+         device_name, xbuddy_path, '--board', self._device.board],
         dryrun=self.dryrun)
 
   def _Deploy(self):
@@ -524,9 +543,10 @@
                       help='Directory for building and deploying chrome.')
   parser.add_argument('--flash', action='store_true', default=False,
                       help='Before running tests, flash the device.')
-  parser.add_argument('--xbuddy', default='xbuddy://remote/{board}/latest',
-                      help='xbuddy link to use for flashing the device '
-                      '(default: %(default)s).')
+  parser.add_argument('--xbuddy',
+                      help='xbuddy link to use for flashing the device. Will '
+                      "default to the board's version used in the cros "
+                      'chrome-sdk if available, or "latest" otherwise.')
   parser.add_argument('--deploy', action='store_true', default=False,
                       help='Before running tests, deploy chrome, '
                       '--build-dir must be specified.')
diff --git a/lib/cros_test_unittest.py b/lib/cros_test_unittest.py
index fbffece..077511b 100644
--- a/lib/cros_test_unittest.py
+++ b/lib/cros_test_unittest.py
@@ -95,14 +95,18 @@
         cros_set_lsb_release.LSB_KEY_VERSION: '12900.0.0',
     }
     self._tester.Run()
-    self.assertCommandContains(['cros', 'flash', 'localhost',
-                                'xbuddy://remote/octopus/latest'])
+    self.assertCommandContains([
+        os.path.join(constants.CHROMITE_BIN_DIR, 'cros'),
+        'flash', 'ssh://localhost:9222',
+        'xbuddy://remote/octopus-release/latest',])
 
     # Specify an xbuddy link.
     self._tester.xbuddy = 'xbuddy://remote/octopus/R82-12901.0.0'
     self._tester.Run()
-    self.assertCommandContains(['cros', 'flash', 'localhost',
-                                'xbuddy://remote/octopus/R82-12901.0.0'])
+    self.assertCommandContains([
+        os.path.join(constants.CHROMITE_BIN_DIR, 'cros'),
+        'flash', 'ssh://localhost:9222',
+        'xbuddy://remote/octopus/R82-12901.0.0'])
 
   def testFlashSkip(self):
     """Tests flash command is skipped when not needed."""
@@ -113,9 +117,10 @@
     }
     self._tester.xbuddy = 'xbuddy://remote/octopus/R82-12901.0.0'
     self._tester.Run()
-    self.assertCommandContains(['cros', 'flash', 'localhost',
-                                'xbuddy://remote/octopus/R82-12901.0.0'],
-                               expected=False)
+    self.assertCommandContains(
+        [os.path.join(constants.CHROMITE_BIN_DIR, 'cros'),
+         'flash', 'localhost', 'xbuddy://remote/octopus/R82-12901.0.0'],
+        expected=False)
 
   def testDeployChrome(self):
     """Tests basic deploy chrome command."""