[autotest] Divorce the devserver retry requests and sigalarm.
All dev_server requests made from the client go through a retry
wrapper that uses sigalarm to expedite unresponsive calls. Since
we cannot register our signal handlers with mod wsgi, this cl
modifies the urlopen call to manage an internal socket timeout
instead. In order to continue retrying on other URLErrors, the
urlopen wrapper in site_utils converts socket timeouts to
TimeoutExceptions.
TEST=
1. Added a bad devserver, tried to run_suite on a build that hashed
to said devserver with and without this change and verified that
it only worked in the latter case.
2. Sigalarm still fires when devserver's resolve is called outside wsgi,
and urlopen has a larger timeout.
3. Non TimeoutException URLErrors retry.
4. dev_server_unittest pass.
BUG=chromium:246209
Change-Id: Iec9ef39982f4c8b92e260cf27bf454e624bccfa9
Reviewed-on: https://gerrit.chromium.org/gerrit/58659
Tested-by: Prashanth Balasubramanian <beeps@chromium.org>
Reviewed-by: Alex Miller <milleral@chromium.org>
Commit-Queue: Prashanth Balasubramanian <beeps@chromium.org>
diff --git a/client/common_lib/site_utils.py b/client/common_lib/site_utils.py
index 517ad84..4d8a682 100644
--- a/client/common_lib/site_utils.py
+++ b/client/common_lib/site_utils.py
@@ -8,7 +8,7 @@
import signal
import socket
import time
-import urllib
+import urllib2
from autotest_lib.client.common_lib import base_utils, error, global_config
from autotest_lib.client.cros import constants
@@ -245,7 +245,7 @@
retry_waittime = 1
for _ in range(max_attempts):
try:
- response = urllib.urlopen(status_url)
+ response = urllib2.urlopen(status_url)
except IOError as e:
logging.debug('Error occured when grabbing the lab status: %s.',
e)
@@ -301,6 +301,35 @@
return
+def urlopen_socket_timeout(url, data=None, timeout=5):
+ """
+ Wrapper to urllib2.urlopen with a socket timeout.
+
+ This method will convert all socket timeouts to
+ TimeoutExceptions, so we can use it in conjunction
+ with the rpc retry decorator and continue to handle
+ other URLErrors as we see fit.
+
+ @param url: The url to open.
+ @param data: The data to send to the url (eg: the urlencoded dictionary
+ used with a POST call).
+ @param timeout: The timeout for this urlopen call.
+
+ @return: The response of the urlopen call.
+
+ @raises: error.TimeoutException when a socket timeout occurs.
+ """
+ old_timeout = socket.getdefaulttimeout()
+ socket.setdefaulttimeout(timeout)
+ try:
+ return urllib2.urlopen(url, data=data)
+ except urllib2.URLError as e:
+ if type(e.reason) is socket.timeout:
+ raise error.TimeoutException(str(e))
+ finally:
+ socket.setdefaulttimeout(old_timeout)
+
+
def get_sheriffs():
"""
Polls the javascript file that holds the identity of the sheriff and