auto_updater: Correction in LabTransfer.CheckPayloads().

The auto_updater_transfer.LabTransfer.CheckPayloads() method
is a bit flaky and adding the log_output=True option mostly corrects
this. This is a possibly a timing issue as the curl command within
CheckPayloads does not download anything. This is a quick fix and has
been called out as such.

BUG=chromium:1001312
TEST=Ran inside chroot: auto_updater_transfer_unittest,
auto_updater_unnittest, manual tests.

Change-Id: I632d387d24298810f4db8df74ba7eacc70c461b5
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/1951826
Tested-by: Sanika Kulkarni <sanikak@chromium.org>
Auto-Submit: Sanika Kulkarni <sanikak@chromium.org>
Commit-Queue: Sanika Kulkarni <sanikak@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
diff --git a/lib/auto_updater_transfer.py b/lib/auto_updater_transfer.py
index 0920d6f..efa62bf 100644
--- a/lib/auto_updater_transfer.py
+++ b/lib/auto_updater_transfer.py
@@ -387,10 +387,19 @@
     super(LabTransfer, self).__init__(*args, **kwargs)
 
   def _CheckPayloads(self, payload_name):
+    """Runs the curl command that checks if payloads have been staged."""
     payload_url = self._GetStagedUrl(staged_filename=payload_name,
                                      build_id=self._payload_dir)
     try:
-      retry_util.RunCurl(['-I', payload_url, '--fail'])
+      # TODO(crbug.com/1033187): Remove log_output parameter passed to
+      # retry_util.RunCurl after the bug is fixed. The log_output=True option
+      # has been added to correct what seems to be a timing issue in
+      # retry_util.RunCurl. The error ((23) Failed writing body) is usually
+      # observed when a piped program closes the read pipe before the curl
+      # command has finished writing. log_output forces the read pipe to stay
+      # open, thus avoiding the failure.
+      retry_util.RunCurl(curl_args=['-I', payload_url, '--fail'],
+                         log_output=True)
     except retry_util.DownloadError as e:
       raise ChromiumOSTransferError('Payload %s does not exist at %s: %s' %
                                     (payload_name, payload_url, e))
diff --git a/lib/auto_updater_transfer_unittest.py b/lib/auto_updater_transfer_unittest.py
index 8fe6a0c..bdbe20f 100644
--- a/lib/auto_updater_transfer_unittest.py
+++ b/lib/auto_updater_transfer_unittest.py
@@ -746,16 +746,20 @@
                        'test_stateful.tgz')
       self.PatchObject(retry_util, 'RunCurl')
 
-      expected = [['-I', 'http://0.0.0.0:8000/static/board-release/12345.6.7/'
-                   'test_update.gz', '--fail'],
-                  ['-I', 'http://0.0.0.0:8000/static/board-release/12345.6.7/'
-                   'test_update.gz.json', '--fail'],
-                  ['-I', 'http://0.0.0.0:8000/static/board-release/12345.6.7/'
-                   'test_stateful.tgz', '--fail']]
+      expected = [
+          {'curl_args': ['-I', 'http://0.0.0.0:8000/static/board-release/'
+                               '12345.6.7/test_update.gz', '--fail'],
+           'log_output': True},
+          {'curl_args': ['-I', 'http://0.0.0.0:8000/static/board-release/'
+                               '12345.6.7/test_update.gz.json', '--fail'],
+           'log_output': True},
+          {'curl_args': ['-I', 'http://0.0.0.0:8000/static/board-release/'
+                               '12345.6.7/test_stateful.tgz', '--fail'],
+           'log_output': True}]
 
       CrOS_LabTransfer.CheckPayloads()
       self.assertListEqual(retry_util.RunCurl.call_args_list,
-                           [mock.call(x) for x in expected])
+                           [mock.call(**x) for x in expected])
 
   def testCheckPayloadsNoStatefulTransfer(self):
     """Test auto_updater_transfer.CheckPayloads.
@@ -770,14 +774,17 @@
           transfer_stateful_update=False)
       self.PatchObject(retry_util, 'RunCurl')
 
-      expected = [['-I', 'http://0.0.0.0:8000/static/board-release/12345.6.7/'
-                   'test_update.gz', '--fail'],
-                  ['-I', 'http://0.0.0.0:8000/static/board-release/12345.6.7/'
-                   'test_update.gz.json', '--fail']]
+      expected = [
+          {'curl_args': ['-I', 'http://0.0.0.0:8000/static/board-release/'
+                               '12345.6.7/test_update.gz', '--fail'],
+           'log_output': True},
+          {'curl_args': ['-I', 'http://0.0.0.0:8000/static/board-release/'
+                               '12345.6.7/test_update.gz.json', '--fail'],
+           'log_output': True}]
 
       CrOS_LabTransfer.CheckPayloads()
       self.assertListEqual(retry_util.RunCurl.call_args_list,
-                           [mock.call(x) for x in expected])
+                           [mock.call(**x) for x in expected])
 
   def testCheckPayloadsNoRootfsTransfer(self):
     """Test auto_updater_transfer.CheckPayloads.
@@ -793,12 +800,14 @@
                        'test_stateful.tgz')
       self.PatchObject(retry_util, 'RunCurl')
 
-      expected = [['-I', 'http://0.0.0.0:8000/static/board-release/12345.6.7/'
-                   'test_stateful.tgz', '--fail']]
+      expected = [
+          {'curl_args': ['-I', 'http://0.0.0.0:8000/static/board-release/'
+                               '12345.6.7/test_stateful.tgz', '--fail'],
+           'log_output': True}]
 
       CrOS_LabTransfer.CheckPayloads()
       self.assertListEqual(retry_util.RunCurl.call_args_list,
-                           [mock.call(x) for x in expected])
+                           [mock.call(**x) for x in expected])
 
   def testCheckPayloadsDownloadError(self):
     """Test auto_updater_transfer.CheckPayloads.