Repository: urllib3/urllib3

Issue:
Running `tox -e gae` is broken on current master
Extracted from #1182:

```console
$ tox -e gae
GLOB sdist-make: /Users/alexwlchan/repos/urllib3/setup.py
gae inst-nodeps: /Users/alexwlchan/repos/urllib3/.tox/dist/urllib3-dev.zip
gae installed: appdirs==1.4.3,backports.ssl-match-hostname==3.5.0.1,certifi==2017.4.17,coverage==3.7.1,funcsigs==1.0.2,mock==1.3.0,nose==1.3.7,nose-exclude==0.4.1,NoseGAE==0.5.7,packaging==16.8,pbr==3.0.1,pkginfo==1.4.1,pluggy==0.3.1,psutil==4.3.1,py==1.4.33,pyparsing==2.2.0,PySocks==1.5.6,pytest==3.1.0,requests==2.14.2,six==1.10.0,tornado==4.2.1,tox==2.1.1,twine==1.5.0,urllib3===dev,virtualenv==15.1.0
gae runtests: PYTHONHASHSEED='2409600760'
gae runtests: commands[0] | nosetests -c /Users/alexwlchan/repos/urllib3/test/appengine/nose.cfg test/appengine
Traceback (most recent call last):
  File ".tox/gae/bin/nosetests", line 11, in <module>
    sys.exit(run_exit())
  File "/Users/alexwlchan/repos/urllib3/.tox/gae/lib/python2.7/site-packages/nose/core.py", line 121, in __init__
    **extra_args)
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/main.py", line 94, in __init__
    self.parseArgs(argv)
  File "/Users/alexwlchan/repos/urllib3/.tox/gae/lib/python2.7/site-packages/nose/core.py", line 145, in parseArgs
    self.config.configure(argv, doc=self.usage())
  File "/Users/alexwlchan/repos/urllib3/.tox/gae/lib/python2.7/site-packages/nose/config.py", line 346, in configure
    self.plugins.configure(options, self)
  File "/Users/alexwlchan/repos/urllib3/.tox/gae/lib/python2.7/site-packages/nose/plugins/manager.py", line 284, in configure
    cfg(options, config)
  File "/Users/alexwlchan/repos/urllib3/.tox/gae/lib/python2.7/site-packages/nose/plugins/manager.py", line 99, in __call__
    return self.call(*arg, **kw)
  File "/Users/alexwlchan/repos/urllib3/.tox/gae/lib/python2.7/site-packages/nose/plugins/manager.py", line 167, in simple
    result = meth(*arg, **kw)
  File "/Users/alexwlchan/repos/urllib3/.tox/gae/lib/python2.7/site-packages/nosegae.py", line 91, in configure
    import dev_appserver
ImportError: No module named dev_appserver
ERROR: InvocationError: '/Users/alexwlchan/repos/urllib3/.tox/gae/bin/nosetests -c /Users/alexwlchan/repos/urllib3/test/appengine/nose.cfg test/appengine'
________________________________________________________________________________ summary _________________________________________________________________________________
ERROR:   gae: commands failed
```


Discussion:
Hmm. I found [the most recent successful Travis job](https://travis-ci.org/shazow/urllib3/jobs/236341107), and pinned based on the requirements reported by tox:

```console
$ cat test/appengine/requirements.txt
requests==2.14.2
appdirs==1.4.3
backports.ssl-match-hostname==3.5.0.1
certifi==2017.4.17
coverage==3.7.1
funcsigs==1.0.2
mock==1.3.0
nose==1.3.7
nose-exclude==0.4.1
NoseGAE==0.5.7
packaging==16.8
pbr==3.0.1
pluggy==0.3.1
psutil==4.3.1
py==1.4.33
pyparsing==2.2.0
PySocks==1.5.6
requests==2.14.2
six==1.10.0
tornado==4.2.1
tox==2.1.1
twine==1.5.0
urllib3===dev
virtualenv==15.1.0
```

Same issue.
Interesting, this passes on Travis, with a matching set of versions – see https://travis-ci.org/shazow/urllib3/jobs/236925046 – but not on my local machine.
But it doesn’t pass in Travis on my fork – https://travis-ci.org/alexwlchan/urllib3/jobs/236924925 – I wonder, is there something dodgy about the Travis cache for urllib3 that’s masking the bug?
@alexwlchan yes, sending a PR to fix shortly.

Resolving patch:
diff --git a/_travis/fetch_gae_sdk.py b/_travis/fetch_gae_sdk.py
deleted file mode 100644
--- a/_travis/fetch_gae_sdk.py
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright 2015 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Retrieved from https://github.com/Google/oauth2client
-
-"""Fetch the most recent GAE SDK and decompress it in the current directory.
-
-Usage:
-    fetch_gae_sdk.py [<dest_dir>]
-
-Current releases are listed here:
-    https://www.googleapis.com/storage/v1/b/appengine-sdks/o?prefix=featured
-"""
-from __future__ import print_function
-
-import json
-import os
-import StringIO
-import sys
-import urllib2
-import zipfile
-
-
-_SDK_URL = (
-    'https://www.googleapis.com/storage/v1/b/appengine-sdks/o?prefix=featured')
-
-
-def get_gae_versions():
-    try:
-        version_info_json = urllib2.urlopen(_SDK_URL).read()
-    except:
-        return {}
-    try:
-        version_info = json.loads(version_info_json)
-    except:
-        return {}
-    return version_info.get('items', {})
-
-
-def _version_tuple(v):
-    version_string = os.path.splitext(v['name'])[0].rpartition('_')[2]
-    return tuple(int(x) for x in version_string.split('.'))
-
-
-def get_sdk_urls(sdk_versions):
-    python_releases = [v for v in sdk_versions
-                       if v['name'].startswith('featured/google_appengine')]
-    current_releases = sorted(python_releases, key=_version_tuple,
-                              reverse=True)
-    return [release['mediaLink'] for release in current_releases]
-
-
-def main(argv):
-    if len(argv) > 2:
-        print('Usage: {0} [<destination_dir>]'.format(argv[0]))
-        return 1
-    if len(argv) > 1:
-        dest_dir = argv[1]
-    else:
-        try:
-            dest_dir = os.path.dirname(os.environ['GAE_PYTHONPATH'])
-        except IndexError:
-            dest_dir = '.'
-    if not os.path.exists(dest_dir):
-        os.makedirs(dest_dir)
-
-    if os.path.exists(os.path.join(dest_dir, 'google_appengine')):
-        print('GAE SDK already installed at {0}, exiting.'.format(dest_dir))
-        return 0
-
-    sdk_versions = get_gae_versions()
-    if not sdk_versions:
-        print('Error fetching GAE SDK version info')
-        return 1
-    sdk_urls = get_sdk_urls(sdk_versions)
-    for sdk_url in sdk_urls:
-        try:
-            sdk_contents = StringIO.StringIO(urllib2.urlopen(sdk_url).read())
-            break
-        except:
-            pass
-    else:
-        print('Could not read SDK from any of ', sdk_urls)
-        return 1
-    sdk_contents.seek(0)
-    try:
-        with zipfile.ZipFile(sdk_contents) as zip_contents:
-            zip_contents.extractall(dest_dir)
-    except:
-        print('Error extracting SDK contents')
-        return 1
-
-
-if __name__ == '__main__':
-    sys.exit(main(sys.argv[:]))


Test patch:
diff --git a/test/appengine/requirements.txt b/test/appengine/requirements.txt
--- a/test/appengine/requirements.txt
+++ b/test/appengine/requirements.txt
@@ -1 +1 @@
-NoseGAE==0.5.7
+NoseGAE==0.5.10