Skip to content
This repository has been archived by the owner on Nov 5, 2019. It is now read-only.

Add a timeout for GCE detection. #101

Merged
merged 1 commit into from
Dec 19, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions oauth2client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import json
import logging
import os
import socket
import sys
import time
import six
Expand Down Expand Up @@ -930,12 +931,22 @@ def _detect_gce_environment(urlopen=None):
Compute Engine.
"""
urlopen = urlopen or urllib.request.urlopen

# Note: the explicit `timeout` below is a workaround. The underlying
# issue is that resolving an unknown host on some networks will take
# 20-30 seconds; making this timeout short fixes the issue, but
# could lead to false negatives in the event that we are on GCE, but
# the metadata resolution was particularly slow. The latter case is
# "unlikely".
try:
response = urlopen('http://metadata.google.internal')
response = urlopen('http://metadata.google.internal/', timeout=1)

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

return any('Metadata-Flavor: Google' in header
for header in response.info().headers)
except urllib.error.URLError:
except socket.timeout:
logger.info('Timeout attempting to reach GCE metadata service.')
return False
except urllib.error.URLError as e:
if isinstance(getattr(e, 'reason', None), socket.timeout):
logger.info('Timeout attempting to reach GCE metadata service.')
return False


Expand Down
44 changes: 12 additions & 32 deletions tests/test_oauth2client.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@
import base64
import datetime
import json
try:
from mox3 import mox
except ImportError:
import mox
import os
import time
import unittest

import mock
import six
from six.moves import urllib

Expand Down Expand Up @@ -208,37 +206,19 @@ def test_get_environment_gae_local(self):

def test_get_environment_gce_production(self):
os.environ['SERVER_SOFTWARE'] = ''
mockResponse = MockResponse(['Metadata-Flavor: Google\r\n'])

m = mox.Mox()

urllib2_urlopen = m.CreateMock(object)
urllib2_urlopen.__call__(('http://metadata.google.internal'
)).AndReturn(mockResponse)

m.ReplayAll()

self.assertEqual('GCE_PRODUCTION', _get_environment(urllib2_urlopen))

m.UnsetStubs()
m.VerifyAll()
with mock.patch.object(urllib.request, 'urlopen') as urlopen:

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

urlopen.return_value = MockResponse(['Metadata-Flavor: Google\r\n'])
self.assertEqual('GCE_PRODUCTION', _get_environment())
urlopen.assert_called_once_with(
'http://metadata.google.internal/', timeout=1)

def test_get_environment_unknown(self):
os.environ['SERVER_SOFTWARE'] = ''
mockResponse = MockResponse([])

m = mox.Mox()

urllib2_urlopen = m.CreateMock(object)
urllib2_urlopen.__call__(('http://metadata.google.internal'
)).AndReturn(mockResponse)

m.ReplayAll()

self.assertEqual(DEFAULT_ENV_NAME, _get_environment(urllib2_urlopen))

m.UnsetStubs()
m.VerifyAll()
with mock.patch.object(urllib.request, 'urlopen') as urlopen:
urlopen.return_value = MockResponse([])
self.assertEqual(DEFAULT_ENV_NAME, _get_environment())
urlopen.assert_called_once_with(
'http://metadata.google.internal/', timeout=1)

def test_get_environment_variable_file(self):
environment_variable_file = datafile(
Expand Down
3 changes: 2 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ envlist = py26,py27,py33,py34,pypy,cover
[testenv]
basedeps = keyring
mox3
mock

This comment was marked as spam.

This comment was marked as spam.

pycrypto==2.6
django>=1.5,<1.6
webtest
nose
deps = {[testenv]basedeps}
pyopenssl==0.14
setenv = PYTHONPATH=../google_appengine
commands = nosetests --ignore-files=test_appengine\.py
commands = nosetests --ignore-files=test_appengine\.py {posargs}

# whitelist
branches:
Expand Down