devserver: stat explicit GS artifact files via getacl

With this change, when an artifact file name does not contain glob
wildcards, we will first attempt to stat its existence via gsutil
getacl. Uses:

* It allows us to stage files that do not appear in the manifest
  (UPLOADED file) on the GS directory, such as autotest tarballs that
  are being uploaded after the fact by paygen (see associated bug).
  Note that getacl is successful iff the file name maps to a single file
  that is present in the archive directory.

* For all other cases, it will just fall back to the existing methods,
  namely reading the manifest file, or resorting to gsutil ls.

BUG=chromium:275750
TEST=Unit tests

Change-Id: Id4d5236b4a781db23d3d78ebf492387ebb74bfb8
Reviewed-on: https://chromium-review.googlesource.com/167435
Tested-by: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Chris Sosa <sosa@chromium.org>
Commit-Queue: Gilad Arnold <garnold@chromium.org>
diff --git a/gsutil_util_unittest.py b/gsutil_util_unittest.py
index 0a493fc..7dc1466 100755
--- a/gsutil_util_unittest.py
+++ b/gsutil_util_unittest.py
@@ -93,6 +93,30 @@
     self.assertEqual([name], returned_names)
     self.mox.VerifyAll()
 
+  def testGetGSNamesWithWaitWithDirectStat(self):
+    """We should directly stat an artifact whose name is fully spelled out."""
+    archive_url = ('gs://chromeos-image-archive/x86-mario-release/'
+                   'R17-1413.0.0-a1-b1346')
+    name = 'chromeos_R17-1413.0.0-a1_x86-mario_full_dev.bin'
+    pattern = 'chromeos_R17-1413.0.0-a1_x86-mario_full_dev.bin'
+    mock_data = 'mock data\nmock_data\nmock_data'
+    msg = 'UNIT TEST'
+
+    self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
+
+    # GSUtil cat gs://archive_url_prefix/UPLOADED.
+    gsutil_util.GSUtilRun(mox.StrContains('gsutil getacl %s/%s' %
+                                          (archive_url, pattern)),
+                          mox.IgnoreArg()).AndReturn(
+                              '%s\n%s' % (mock_data, name))
+
+    self.mox.ReplayAll()
+    # Timeout explicitly set to 0 to test that we always run at least once.
+    returned_names = gsutil_util.GetGSNamesWithWait(
+        pattern, archive_url, msg, delay=1, timeout=0)
+    self.assertEqual([name], returned_names)
+    self.mox.VerifyAll()
+
   def testGetGSNamesWithWaitWithRetry(self):
     """Test that we can poll until all target artifacts are available."""
     archive_url = ('gs://chromeos-image-archive/x86-mario-release/'