Index: test/lib/TestGyp.py |
diff --git a/test/lib/TestGyp.py b/test/lib/TestGyp.py |
index 3cea15e7bfcf0c52dc30654c08583775f95260db..ff954189da93048ef6964d3d44d840a8dfa37686 100644 |
--- a/test/lib/TestGyp.py |
+++ b/test/lib/TestGyp.py |
@@ -10,12 +10,14 @@ import collections |
from contextlib import contextmanager |
import itertools |
import os |
+import random |
import re |
import shutil |
import stat |
import subprocess |
import sys |
import tempfile |
+import time |
import TestCmd |
import TestCommon |
@@ -552,7 +554,7 @@ class TestGypAndroid(TestGypBase): |
print stderr.read() |
self.fail_test() |
- def _call_adb(self, command): |
+ def _call_adb(self, command, timeout=15, retry=3): |
""" Calls the provided adb command. |
If the command fails, the test fails. |
@@ -571,23 +573,47 @@ class TestGypAndroid(TestGypBase): |
if is_shell: |
command = [command[0], '%s; echo "\n$?";' % ' '.join(command[1:])] |
adb_command += command |
- if subprocess.call(adb_command, stdout=adb_out, stderr=adb_err) != 0: |
- self._adb_failure(adb_command, None, adb_out, adb_err) |
- else: |
+ |
+ for attempt in xrange(1, retry + 1): |
adb_out.seek(0) |
- output = adb_out.read() |
- if is_shell: |
- output = output.splitlines(True) |
+ adb_out.truncate(0) |
+ adb_err.seek(0) |
+ adb_err.truncate(0) |
+ proc = subprocess.Popen(adb_command, stdout=adb_out, stderr=adb_err) |
+ deadline = time.time() + timeout |
bradn
2014/08/22 16:13:32
I assume there's no need for exponential backoff?
|
+ timed_out = False |
+ while proc.poll() is None and not timed_out: |
+ time.sleep(1) |
+ timed_out = time.time() > deadline |
+ if timed_out: |
+ print 'Timeout for command %s (attempt %d of %s)' % ( |
+ adb_command, attempt, retry) |
try: |
- output[-2] = output[-2].rstrip('\r\n') |
- output, rc = (''.join(output[:-1]), int(output[-1])) |
- except ValueError: |
- self._adb_failure(adb_command, 'unexpected output format', |
- adb_out, adb_err) |
- if rc != 0: |
- self._adb_failure(adb_command, 'exited with %d' % rc, adb_out, |
- adb_err) |
- return output |
+ proc.kill() |
+ except: |
+ pass |
+ else: |
+ break |
+ |
+ if proc.returncode != 0: # returncode is None in the case of a timeout. |
+ self._adb_failure( |
+ adb_command, 'retcode=%s' % proc.returncode, adb_out, adb_err) |
+ return |
+ |
+ adb_out.seek(0) |
+ output = adb_out.read() |
+ if is_shell: |
+ output = output.splitlines(True) |
+ try: |
+ output[-2] = output[-2].rstrip('\r\n') |
+ output, rc = (''.join(output[:-1]), int(output[-1])) |
+ except ValueError: |
+ self._adb_failure(adb_command, 'unexpected output format', |
+ adb_out, adb_err) |
+ if rc != 0: |
+ self._adb_failure(adb_command, 'exited with %d' % rc, adb_out, |
+ adb_err) |
+ return output |
def run_built_executable(self, name, *args, **kw): |
""" |
@@ -620,7 +646,9 @@ class TestGypAndroid(TestGypBase): |
out = self._call_adb( |
['shell', 'LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%s' % storage, |
- device_executable]) |
+ device_executable], |
+ timeout=60, |
+ retry=1) |
out = out.replace('\r\n', '\n') |
self._complete(out, kw.pop('stdout', None), None, None, None, match) |
finally: |