Commit e2dde5bd authored by Paul Ganssle's avatar Paul Ganssle Committed by GitHub

Merge pull request #1418 from pganssle/egg_race_condition

Egg race condition
parents 5f510913 67f190ad
Solved race in when creating egg cache directories.
......@@ -47,6 +47,11 @@ except ImportError:
# Python 3.2 compatibility
import imp as _imp
try:
FileExistsError
except NameError:
FileExistsError = OSError
from pkg_resources.extern import six
from pkg_resources.extern.six.moves import urllib, map, filter
......@@ -3030,7 +3035,10 @@ def _bypass_ensure_directory(path):
dirname, filename = split(path)
if dirname and filename and not isdir(dirname):
_bypass_ensure_directory(dirname)
try:
mkdir(dirname, 0o755)
except FileExistsError:
pass
def split_sections(s):
......
......@@ -12,6 +12,11 @@ import stat
import distutils.dist
import distutils.command.install_egg_info
try:
from unittest import mock
except ImportError:
import mock
from pkg_resources.extern.six.moves import map
from pkg_resources.extern.six import text_type, string_types
......@@ -138,8 +143,34 @@ class TestResourceManager:
message = "Unexpected type from get_cache_path: " + type_
assert isinstance(path, string_types), message
def test_get_cache_path_race(self, tmpdir):
# Patch to os.path.isdir to create a race condition
def patched_isdir(dirname, unpatched_isdir=pkg_resources.isdir):
patched_isdir.dirnames.append(dirname)
was_dir = unpatched_isdir(dirname)
if not was_dir:
os.makedirs(dirname)
return was_dir
patched_isdir.dirnames = []
# Get a cache path with a "race condition"
mgr = pkg_resources.ResourceManager()
mgr.set_extraction_path(str(tmpdir))
archive_name = os.sep.join(('foo', 'bar', 'baz'))
with mock.patch.object(pkg_resources, 'isdir', new=patched_isdir):
mgr.get_cache_path(archive_name)
# Because this test relies on the implementation details of this
# function, these assertions are a sentinel to ensure that the
# test suite will not fail silently if the implementation changes.
called_dirnames = patched_isdir.dirnames
assert len(called_dirnames) == 2
assert called_dirnames[0].split(os.sep)[-2:] == ['foo', 'bar']
assert called_dirnames[1].split(os.sep)[-1:] == ['foo']
class TestIndependence:
"""
Tests to ensure that pkg_resources runs independently from setuptools.
"""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment