Commit 485dcab6 authored by maruel@chromium.org's avatar maruel@chromium.org

Fix the case where a dep not processed could be set as a requirement.

This would result in a hang during gclient sync.

Includes regression test.

R=dpranke@chromium.org
BUG=
TEST=


Review URL: http://codereview.chromium.org/7885008

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@101070 0039d316-1c4b-4281-b951-d872f2087c98
parent 69bc538f
...@@ -224,12 +224,13 @@ class Dependency(GClientKeywords, gclient_utils.WorkItem): ...@@ -224,12 +224,13 @@ class Dependency(GClientKeywords, gclient_utils.WorkItem):
if isinstance(self.url, self.FromImpl): if isinstance(self.url, self.FromImpl):
self.requirements.add(self.url.module_name) self.requirements.add(self.url.module_name)
if self.name: if self.name and self.should_process:
def yield_full_tree(root): def yield_full_tree(root):
"""Depth-first recursion.""" """Depth-first recursion."""
yield root yield root
for i in root.dependencies: for i in root.dependencies:
for j in yield_full_tree(i): for j in yield_full_tree(i):
if j.should_process:
yield j yield j
for obj in yield_full_tree(self.root_parent()): for obj in yield_full_tree(self.root_parent()):
......
...@@ -454,10 +454,11 @@ def GetGClientRootAndEntries(path=None): ...@@ -454,10 +454,11 @@ def GetGClientRootAndEntries(path=None):
class WorkItem(object): class WorkItem(object):
"""One work item.""" """One work item."""
def __init__(self):
# A list of string, each being a WorkItem name. # A list of string, each being a WorkItem name.
requirements = [] self.requirements = []
# A unique string representing this work item. # A unique string representing this work item.
name = None self.name = None
def run(self, work_queue): def run(self, work_queue):
"""work_queue is passed as keyword argument so it should be """work_queue is passed as keyword argument so it should be
...@@ -548,7 +549,20 @@ class ExecutionQueue(object): ...@@ -548,7 +549,20 @@ class ExecutionQueue(object):
# We're done. # We're done.
break break
# We need to poll here otherwise Ctrl-C isn't processed. # We need to poll here otherwise Ctrl-C isn't processed.
try:
self.ready_cond.wait(10) self.ready_cond.wait(10)
except KeyboardInterrupt:
# Help debugging by printing some information:
print >> sys.stderr, (
('\nAllowed parallel jobs: %d\n# queued: %d\nRan: %s\n'
'Running: %d') % (
self.jobs,
len(self.queued),
', '.join(self.ran),
len(self.running)))
for i in self.queued:
print >> sys.stderr, '%s: %s' % (i.name, ', '.join(i.requirements))
raise
# Something happened: self.enqueue() or a thread terminated. Loop again. # Something happened: self.enqueue() or a thread terminated. Loop again.
finally: finally:
self.ready_cond.release() self.ready_cond.release()
......
...@@ -88,6 +88,8 @@ class GclientTest(trial_dir.TestCase): ...@@ -88,6 +88,8 @@ class GclientTest(trial_dir.TestCase):
# fetched until 'src' is done. # fetched until 'src' is done.
# jobs is the number of parallel jobs simulated. reverse is to reshuffle the # jobs is the number of parallel jobs simulated. reverse is to reshuffle the
# list to see if it is still processed in order correctly. # list to see if it is still processed in order correctly.
# Also test that a From() dependency that should not be processed is listed
# as a requirement.
parser = gclient.Parser() parser = gclient.Parser()
options, args = parser.parse_args(['--jobs', jobs]) options, args = parser.parse_args(['--jobs', jobs])
write( write(
...@@ -101,9 +103,11 @@ class GclientTest(trial_dir.TestCase): ...@@ -101,9 +103,11 @@ class GclientTest(trial_dir.TestCase):
os.path.join('foo', 'DEPS'), os.path.join('foo', 'DEPS'),
'deps = {\n' 'deps = {\n'
' "foo/dir1": "/dir1",\n' ' "foo/dir1": "/dir1",\n'
# This one will depend on dir1/dir2 in bar.
' "foo/dir1/dir2/dir3": "/dir1/dir2/dir3",\n' ' "foo/dir1/dir2/dir3": "/dir1/dir2/dir3",\n'
' "foo/dir1/dir4": "/dir1/dir4",\n'
' "foo/dir1/dir2/dir3/dir4": "/dir1/dir2/dir3/dir4",\n' ' "foo/dir1/dir2/dir3/dir4": "/dir1/dir2/dir3/dir4",\n'
' "foo/dir1/dir2/dir5/dir6":\n'
' From("foo/dir1/dir2/dir3/dir4", "foo/dir1/dir2"),\n'
'}') '}')
write( write(
os.path.join('bar', 'DEPS'), os.path.join('bar', 'DEPS'),
...@@ -114,6 +118,14 @@ class GclientTest(trial_dir.TestCase): ...@@ -114,6 +118,14 @@ class GclientTest(trial_dir.TestCase):
os.path.join('bar/empty', 'DEPS'), os.path.join('bar/empty', 'DEPS'),
'deps = {\n' 'deps = {\n'
'}') '}')
# Test From()
write(
os.path.join('foo/dir1/dir2/dir3/dir4', 'DEPS'),
'deps = {\n'
# This one should not be fetched or set as a requirement.
' "foo/dir1/dir2/dir5": "svn://example.com/x",\n'
' "foo/dir1/dir2": "/dir1/another",\n'
'}')
obj = gclient.GClient.LoadCurrentConfig(options) obj = gclient.GClient.LoadCurrentConfig(options)
self._check_requirements(obj.dependencies[0], {}) self._check_requirements(obj.dependencies[0], {})
...@@ -139,9 +151,10 @@ class GclientTest(trial_dir.TestCase): ...@@ -139,9 +151,10 @@ class GclientTest(trial_dir.TestCase):
self.assertEquals( self.assertEquals(
[ [
'svn://example.com/foo/dir1', 'svn://example.com/foo/dir1',
'svn://example.com/foo/dir1/dir4',
'svn://example.com/foo/dir1/dir2/dir3', 'svn://example.com/foo/dir1/dir2/dir3',
'svn://example.com/foo/dir1/dir2/dir3/dir4', 'svn://example.com/foo/dir1/dir2/dir3/dir4',
# TODO(maruel): This is probably wrong.
'svn://example.com/foo/dir1/dir2/dir3/dir4/dir1/another',
], ],
actual) actual)
self._check_requirements( self._check_requirements(
...@@ -151,7 +164,8 @@ class GclientTest(trial_dir.TestCase): ...@@ -151,7 +164,8 @@ class GclientTest(trial_dir.TestCase):
'foo/dir1/dir2/dir3': ['foo', 'foo/dir1', 'foo/dir1/dir2'], 'foo/dir1/dir2/dir3': ['foo', 'foo/dir1', 'foo/dir1/dir2'],
'foo/dir1/dir2/dir3/dir4': 'foo/dir1/dir2/dir3/dir4':
['foo', 'foo/dir1', 'foo/dir1/dir2', 'foo/dir1/dir2/dir3'], ['foo', 'foo/dir1', 'foo/dir1/dir2', 'foo/dir1/dir2/dir3'],
'foo/dir1/dir4': ['foo', 'foo/dir1'], 'foo/dir1/dir2/dir5/dir6':
['foo', 'foo/dir1', 'foo/dir1/dir2', 'foo/dir1/dir2/dir3/dir4'],
}) })
self._check_requirements( self._check_requirements(
obj.dependencies[1], obj.dependencies[1],
......
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