Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/env python | |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """Unit tests for gclient.py. | |
| 7 | |
| 8 See gclient_smoketest.py for integration tests. | |
| 9 """ | |
| 10 | |
| 11 import Queue | |
| 12 import logging | |
| 13 import os | |
| 14 import sys | |
| 15 import unittest | |
| 16 | |
| 17 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) | |
| 18 sys.path.insert(0, os.path.dirname(BASE_DIR)) | |
| 19 | |
| 20 import gclient | |
| 21 from tests import trial_dir | |
| 22 | |
| 23 | |
| 24 def write(filename, content): | |
| 25 """Writes the content of a file and create the directories as needed.""" | |
| 26 filename = os.path.abspath(filename) | |
| 27 dirname = os.path.dirname(filename) | |
| 28 if not os.path.isdir(dirname): | |
| 29 os.makedirs(dirname) | |
| 30 with open(filename, 'w') as f: | |
| 31 f.write(content) | |
| 32 | |
| 33 | |
| 34 class SCMMock(object): | |
| 35 def __init__(self, unit_test, url): | |
| 36 self.unit_test = unit_test | |
| 37 self.url = url | |
| 38 | |
| 39 def RunCommand(self, command, options, args, file_list): | |
| 40 self.unit_test.assertEquals('None', command) | |
| 41 self.unit_test.processed.put(self.url) | |
| 42 | |
| 43 def FullUrlForRelativeUrl(self, url): | |
| 44 return self.url + url | |
| 45 | |
| 46 | |
| 47 class GclientTest(trial_dir.TestCase): | |
| 48 def setUp(self): | |
| 49 super(GclientTest, self).setUp() | |
| 50 self.processed = Queue.Queue() | |
| 51 self.previous_dir = os.getcwd() | |
| 52 os.chdir(self.root_dir) | |
| 53 # Manual mocks. | |
| 54 self._old_createscm = gclient.gclient_scm.CreateSCM | |
| 55 gclient.gclient_scm.CreateSCM = self._createscm | |
| 56 self._old_sys_stdout = sys.stdout | |
| 57 sys.stdout = gclient.gclient_utils.MakeFileAutoFlush(sys.stdout) | |
| 58 sys.stdout = gclient.gclient_utils.MakeFileAnnotated(sys.stdout) | |
| 59 | |
| 60 def tearDown(self): | |
| 61 self.assertEquals([], self._get_processed()) | |
| 62 gclient.gclient_scm.CreateSCM = self._old_createscm | |
| 63 sys.stdout = self._old_sys_stdout | |
| 64 os.chdir(self.previous_dir) | |
| 65 super(GclientTest, self).tearDown() | |
| 66 | |
| 67 def _createscm(self, parsed_url, root_dir, name): | |
| 68 self.assertTrue(parsed_url.startswith('svn://example.com/'), parsed_url) | |
| 69 self.assertTrue(root_dir.startswith(self.root_dir), root_dir) | |
| 70 return SCMMock(self, parsed_url) | |
| 71 | |
| 72 def testDependencies(self): | |
| 73 self._dependencies('1', False) | |
| 74 | |
| 75 def testDependenciesReverse(self): | |
| 76 self._dependencies('1', True) | |
| 77 | |
| 78 def testDependenciesJobs(self): | |
| 79 self._dependencies('1000', False) | |
| 80 | |
| 81 def testDependenciesJobsReverse(self): | |
| 82 self._dependencies('1000', True) | |
| 83 | |
| 84 def _dependencies(self, jobs, reverse): | |
| 85 # 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
| |
| 86 # is a dependency 'src' and another 'src/third_party/bar', that bar isn't | |
| 87 # fetched until 'src' is done. | |
| 88 # jobs is the number of parallel jobs simulated. reverse is to reshuffle the | |
| 89 # list to see if it is still processed in order correctly. | |
| 90 parser = gclient.Parser() | |
| 91 options, args = parser.parse_args(['--jobs', jobs]) | |
| 92 write( | |
| 93 '.gclient', | |
| 94 'solutions = [\n' | |
| 95 ' { "name": "foo", "url": "svn://example.com/foo" },\n' | |
| 96 ' { "name": "bar", "url": "svn://example.com/bar" },\n' | |
| 97 ']') | |
| 98 write( | |
| 99 os.path.join('foo', 'DEPS'), | |
| 100 'deps = {\n' | |
| 101 ' "foo/dir1": "/dir1",\n' | |
| 102 ' "foo/dir1/dir2/dir3": "/dir1/dir2/dir3",\n' | |
| 103 ' "foo/dir1/dir4": "/dir1/dir4",\n' | |
| 104 ' "foo/dir1/dir2/dir3/dir4": "/dir1/dir2/dir3/dir4",\n' | |
| 105 '}') | |
| 106 write( | |
| 107 os.path.join('bar', 'DEPS'), | |
| 108 'deps = {\n' | |
| 109 ' "foo/dir1/dir2": "/dir1/dir2",\n' | |
| 110 '}') | |
| 111 | |
| 112 obj = gclient.GClient.LoadCurrentConfig(options) | |
| 113 self._check_requirements(obj.dependencies[0], {}) | |
| 114 self._check_requirements(obj.dependencies[1], {}) | |
| 115 obj.RunOnDeps('None', args) | |
| 116 # The trick here is to manually process the list to make sure it's out of | |
| 117 # order. | |
| 118 obj.dependencies[0].dependencies.sort(key=lambda x: x.name, reverse=reverse) | |
| 119 actual = self._get_processed() | |
| 120 # We don't care of the ordering of this item. | |
| 121 actual.remove('svn://example.com/bar/dir1/dir2') | |
| 122 self.assertEquals( | |
| 123 [ | |
| 124 'svn://example.com/foo', | |
| 125 'svn://example.com/bar', | |
| 126 'svn://example.com/foo/dir1', | |
| 127 'svn://example.com/foo/dir1/dir4', | |
| 128 'svn://example.com/foo/dir1/dir2/dir3', | |
| 129 'svn://example.com/foo/dir1/dir2/dir3/dir4', | |
| 130 ], | |
| 131 actual) | |
| 132 self._check_requirements( | |
| 133 obj.dependencies[0], | |
| 134 { | |
| 135 'foo/dir1': ['foo'], | |
| 136 'foo/dir1/dir2/dir3': ['foo', 'foo/dir1'], | |
| 137 'foo/dir1/dir2/dir3/dir4': ['foo', 'foo/dir1', 'foo/dir1/dir2/dir3'], | |
| 138 'foo/dir1/dir4': ['foo', 'foo/dir1'], | |
| 139 }) | |
| 140 self._check_requirements( | |
| 141 obj.dependencies[1], | |
| 142 { | |
| 143 'foo/dir1/dir2': ['bar'], | |
| 144 }) | |
| 145 | |
| 146 def _check_requirements(self, solution, expected): | |
| 147 for dependency in solution.dependencies: | |
| 148 self.assertEquals(expected.pop(dependency.name), dependency.requirements) | |
| 149 self.assertEquals({}, expected) | |
| 150 | |
| 151 def _get_processed(self): | |
| 152 items = [] | |
| 153 try: | |
| 154 while True: | |
| 155 items.append(self.processed.get_nowait()) | |
| 156 except Queue.Empty: | |
| 157 pass | |
| 158 return items | |
| 159 | |
| 160 | |
| 161 if __name__ == '__main__': | |
| 162 logging.basicConfig( | |
| 163 level=[logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG][ | |
| 164 min(sys.argv.count('-v'), 3)], | |
| 165 format='%(asctime).19s %(levelname)s %(filename)s:' | |
| 166 '%(lineno)s %(message)s') | |
| 167 unittest.main() | |
| OLD | NEW |