Check gclient sync returncode in gclient_sync_retry

This change adds logic to check the return code from running "gclient
sync" in "gclient_sync_retry".  If the "gclient sync" call failed for
reasons other than failing to connect, then still treat it as failure
and pass this information up to our caller (previously, |main| would
implicitly return |None|, which converts to 0, implying that there
was no error, ever if there was).

b/68705114

Change-Id: I6fd35ddc840aa856d7becc8556e2f04cefcbdeb2
diff --git a/gclient_sync_retry.py b/gclient_sync_retry.py
index f8abced..232f657 100644
--- a/gclient_sync_retry.py
+++ b/gclient_sync_retry.py
@@ -38,6 +38,12 @@
   max_runs = 3
   fail_string = 'Failed to connect'
   os.environ['GIT_CURL_VERBOSE'] = '1'
+
+  # Whether any runs were successful or not.  Success is defined to be output
+  # that does not contain |fail_string|, as well as a zero exit code, as the
+  # gclient call could have failed for other reasons.
+  any_succeeded = False
+
   for run in range(1, max_runs + 1):
     sys.stdout.write('Attempt %d\n' % run)
     p = subprocess.Popen(
@@ -45,15 +51,24 @@
         stdout=subprocess.PIPE,
         stderr=subprocess.PIPE,
         stdin=subprocess.PIPE)
-    p_stdout, p_stderr = p.communicate('')
+    p_stdout, p_stderr = p.communicate()
     sys.stdout.write(p_stdout)
     sys.stderr.write(p_stderr)
-    if run < max_runs and (fail_string in p_stderr or fail_string in p_stdout):
+    contains_fail_string = (fail_string in p_stderr) or (
+        fail_string in p_stdout)
+
+    if p.returncode == 0 and not contains_fail_string:
+      any_succeeded = True
+      break
+
+    if run < max_runs and contains_fail_string:
       sys.stdout.write('Retrying gclient sync\n')
       time.sleep(5 * random.randint(0, 2**run - 1))
       continue
     break
 
+  return 0 if any_succeeded else 1
+
 
 if __name__ == '__main__':
   sys.exit(main())