Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Unified Diff: tests/gclient_test.py

Issue 7773001: Add regression test for the parallel jobs dependency issue. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: add comment Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tests/gclient_test.py
diff --git a/tests/gclient_test.py b/tests/gclient_test.py
new file mode 100755
index 0000000000000000000000000000000000000000..065d718d613bd7c7cd4dd3cb6be116a624fdf411
--- /dev/null
+++ b/tests/gclient_test.py
@@ -0,0 +1,167 @@
+#!/usr/bin/env python
+# Copyright (c) 2011 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Unit tests for gclient.py.
+
+See gclient_smoketest.py for integration tests.
+"""
+
+import Queue
+import logging
+import os
+import sys
+import unittest
+
+BASE_DIR = os.path.dirname(os.path.abspath(__file__))
+sys.path.insert(0, os.path.dirname(BASE_DIR))
+
+import gclient
+from tests import trial_dir
+
+
+def write(filename, content):
+ """Writes the content of a file and create the directories as needed."""
+ filename = os.path.abspath(filename)
+ dirname = os.path.dirname(filename)
+ if not os.path.isdir(dirname):
+ os.makedirs(dirname)
+ with open(filename, 'w') as f:
+ f.write(content)
+
+
+class SCMMock(object):
+ def __init__(self, unit_test, url):
+ self.unit_test = unit_test
+ self.url = url
+
+ def RunCommand(self, command, options, args, file_list):
+ self.unit_test.assertEquals('None', command)
+ self.unit_test.processed.put(self.url)
+
+ def FullUrlForRelativeUrl(self, url):
+ return self.url + url
+
+
+class GclientTest(trial_dir.TestCase):
+ def setUp(self):
+ super(GclientTest, self).setUp()
+ self.processed = Queue.Queue()
+ self.previous_dir = os.getcwd()
+ os.chdir(self.root_dir)
+ # Manual mocks.
+ self._old_createscm = gclient.gclient_scm.CreateSCM
+ gclient.gclient_scm.CreateSCM = self._createscm
+ self._old_sys_stdout = sys.stdout
+ sys.stdout = gclient.gclient_utils.MakeFileAutoFlush(sys.stdout)
+ sys.stdout = gclient.gclient_utils.MakeFileAnnotated(sys.stdout)
+
+ def tearDown(self):
+ self.assertEquals([], self._get_processed())
+ gclient.gclient_scm.CreateSCM = self._old_createscm
+ sys.stdout = self._old_sys_stdout
+ os.chdir(self.previous_dir)
+ super(GclientTest, self).tearDown()
+
+ def _createscm(self, parsed_url, root_dir, name):
+ self.assertTrue(parsed_url.startswith('svn://example.com/'), parsed_url)
+ self.assertTrue(root_dir.startswith(self.root_dir), root_dir)
+ return SCMMock(self, parsed_url)
+
+ def testDependencies(self):
+ self._dependencies('1', False)
+
+ def testDependenciesReverse(self):
+ self._dependencies('1', True)
+
+ def testDependenciesJobs(self):
+ self._dependencies('1000', False)
+
+ def testDependenciesJobsReverse(self):
+ self._dependencies('1000', True)
+
+ def _dependencies(self, jobs, reverse):
+ # Verify that dependencies are processed in the right order, e.g. if there
M-A Ruel 2011/08/30 15:07:34 Added a comment to explain what this function chec
+ # is a dependency 'src' and another 'src/third_party/bar', that bar isn't
+ # fetched until 'src' is done.
+ # jobs is the number of parallel jobs simulated. reverse is to reshuffle the
+ # list to see if it is still processed in order correctly.
+ parser = gclient.Parser()
+ options, args = parser.parse_args(['--jobs', jobs])
+ write(
+ '.gclient',
+ 'solutions = [\n'
+ ' { "name": "foo", "url": "svn://example.com/foo" },\n'
+ ' { "name": "bar", "url": "svn://example.com/bar" },\n'
+ ']')
+ write(
+ os.path.join('foo', 'DEPS'),
+ 'deps = {\n'
+ ' "foo/dir1": "/dir1",\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'
+ '}')
+ write(
+ os.path.join('bar', 'DEPS'),
+ 'deps = {\n'
+ ' "foo/dir1/dir2": "/dir1/dir2",\n'
+ '}')
+
+ obj = gclient.GClient.LoadCurrentConfig(options)
+ self._check_requirements(obj.dependencies[0], {})
+ self._check_requirements(obj.dependencies[1], {})
+ obj.RunOnDeps('None', args)
+ # The trick here is to manually process the list to make sure it's out of
+ # order.
+ obj.dependencies[0].dependencies.sort(key=lambda x: x.name, reverse=reverse)
+ actual = self._get_processed()
+ # We don't care of the ordering of this item.
+ actual.remove('svn://example.com/bar/dir1/dir2')
+ self.assertEquals(
+ [
+ 'svn://example.com/foo',
+ 'svn://example.com/bar',
+ '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/dir4',
+ ],
+ actual)
+ self._check_requirements(
+ obj.dependencies[0],
+ {
+ 'foo/dir1': ['foo'],
+ 'foo/dir1/dir2/dir3': ['foo', 'foo/dir1'],
+ 'foo/dir1/dir2/dir3/dir4': ['foo', 'foo/dir1', 'foo/dir1/dir2/dir3'],
+ 'foo/dir1/dir4': ['foo', 'foo/dir1'],
+ })
+ self._check_requirements(
+ obj.dependencies[1],
+ {
+ 'foo/dir1/dir2': ['bar'],
+ })
+
+ def _check_requirements(self, solution, expected):
+ for dependency in solution.dependencies:
+ self.assertEquals(expected.pop(dependency.name), dependency.requirements)
+ self.assertEquals({}, expected)
+
+ def _get_processed(self):
+ items = []
+ try:
+ while True:
+ items.append(self.processed.get_nowait())
+ except Queue.Empty:
+ pass
+ return items
+
+
+if __name__ == '__main__':
+ logging.basicConfig(
+ level=[logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG][
+ min(sys.argv.count('-v'), 3)],
+ format='%(asctime).19s %(levelname)s %(filename)s:'
+ '%(lineno)s %(message)s')
+ unittest.main()
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698