OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Unit tests for gclient.py. | 6 """Unit tests for gclient.py. |
7 | 7 |
8 See gclient_smoketest.py for integration tests. | 8 See gclient_smoketest.py for integration tests. |
9 """ | 9 """ |
10 | 10 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 sys.stdout = self._old_sys_stdout | 65 sys.stdout = self._old_sys_stdout |
66 os.chdir(self.previous_dir) | 66 os.chdir(self.previous_dir) |
67 super(GclientTest, self).tearDown() | 67 super(GclientTest, self).tearDown() |
68 | 68 |
69 def _createscm(self, parsed_url, root_dir, name): | 69 def _createscm(self, parsed_url, root_dir, name): |
70 self.assertTrue(parsed_url.startswith('svn://example.com/'), parsed_url) | 70 self.assertTrue(parsed_url.startswith('svn://example.com/'), parsed_url) |
71 self.assertTrue(root_dir.startswith(self.root_dir), root_dir) | 71 self.assertTrue(root_dir.startswith(self.root_dir), root_dir) |
72 return SCMMock(self, parsed_url) | 72 return SCMMock(self, parsed_url) |
73 | 73 |
74 def testDependencies(self): | 74 def testDependencies(self): |
75 self._dependencies('1', False) | 75 self._dependencies('1') |
76 | |
77 def testDependenciesReverse(self): | |
78 self._dependencies('1', True) | |
79 | 76 |
80 def testDependenciesJobs(self): | 77 def testDependenciesJobs(self): |
81 # TODO(maruel): Reenable once parallel processing works. | 78 self._dependencies('1000') |
82 #self._dependencies('1000', False) | |
83 pass | |
84 | 79 |
85 def testDependenciesJobsReverse(self): | 80 def _dependencies(self, jobs): |
86 # TODO(maruel): Reenable once parallel processing works. | 81 """Verifies that dependencies are processed in the right order. |
87 #self._dependencies('1000', True) | |
88 pass | |
89 | 82 |
90 def _dependencies(self, jobs, reverse): | 83 e.g. if there is a dependency 'src' and another 'src/third_party/bar', that |
91 # Verify that dependencies are processed in the right order, e.g. if there | 84 bar isn't fetched until 'src' is done. |
92 # is a dependency 'src' and another 'src/third_party/bar', that bar isn't | 85 Also test that a From() dependency should not be processed when it is listed |
93 # fetched until 'src' is done. | 86 as a requirement. |
94 # jobs is the number of parallel jobs simulated. reverse is to reshuffle the | 87 |
95 # list to see if it is still processed in order correctly. | 88 Args: |
96 # Also test that a From() dependency that should not be processed is listed | 89 |jobs| is the number of parallel jobs simulated. |
97 # as a requirement. | 90 """ |
98 parser = gclient.Parser() | 91 parser = gclient.Parser() |
99 options, args = parser.parse_args(['--jobs', jobs]) | 92 options, args = parser.parse_args(['--jobs', jobs]) |
100 write( | 93 write( |
101 '.gclient', | 94 '.gclient', |
102 'solutions = [\n' | 95 'solutions = [\n' |
103 ' { "name": "foo", "url": "svn://example.com/foo" },\n' | 96 ' { "name": "foo", "url": "svn://example.com/foo" },\n' |
104 ' { "name": "bar", "url": "svn://example.com/bar" },\n' | 97 ' { "name": "bar", "url": "svn://example.com/bar" },\n' |
105 ' { "name": "bar/empty", "url": "svn://example.com/bar_empty" },\n' | 98 ' { "name": "bar/empty", "url": "svn://example.com/bar_empty" },\n' |
106 ']') | 99 ']') |
107 write( | 100 write( |
108 os.path.join('foo', 'DEPS'), | 101 os.path.join('foo', 'DEPS'), |
109 'deps = {\n' | 102 'deps = {\n' |
110 ' "foo/dir1": "/dir1",\n' | 103 ' "foo/dir1": "/dir1",\n' |
111 # This one will depend on dir1/dir2 in bar. | 104 # This one will depend on dir1/dir2 in bar. |
112 ' "foo/dir1/dir2/dir3": "/dir1/dir2/dir3",\n' | 105 ' "foo/dir1/dir2/dir3": "/dir1/dir2/dir3",\n' |
113 ' "foo/dir1/dir2/dir3/dir4": "/dir1/dir2/dir3/dir4",\n' | 106 ' "foo/dir1/dir2/dir3/dir4": "/dir1/dir2/dir3/dir4",\n' |
114 ' "foo/dir1/dir2/dir5/dir6":\n' | 107 ' "foo/dir1/dir2/dir5/dir6":\n' |
115 ' From("foo/dir1/dir2/dir3/dir4", "foo/dir1/dir2"),\n' | 108 ' From("foo/dir1/dir2/dir3/dir4", "foo/dir1/dir2"),\n' |
116 '}') | 109 '}') |
117 write( | 110 write( |
118 os.path.join('bar', 'DEPS'), | 111 os.path.join('bar', 'DEPS'), |
119 'deps = {\n' | 112 'deps = {\n' |
| 113 # There is two foo/dir1/dir2. This one is fetched as bar/dir1/dir2. |
120 ' "foo/dir1/dir2": "/dir1/dir2",\n' | 114 ' "foo/dir1/dir2": "/dir1/dir2",\n' |
121 '}') | 115 '}') |
122 write( | 116 write( |
123 os.path.join('bar/empty', 'DEPS'), | 117 os.path.join('bar/empty', 'DEPS'), |
124 'deps = {\n' | 118 'deps = {\n' |
125 '}') | 119 '}') |
126 # Test From() | 120 # Test From() |
127 write( | 121 write( |
128 os.path.join('foo/dir1/dir2/dir3/dir4', 'DEPS'), | 122 os.path.join('foo/dir1/dir2/dir3/dir4', 'DEPS'), |
129 'deps = {\n' | 123 'deps = {\n' |
130 # This one should not be fetched or set as a requirement. | 124 # This one should not be fetched or set as a requirement. |
131 ' "foo/dir1/dir2/dir5": "svn://example.com/x",\n' | 125 ' "foo/dir1/dir2/dir5": "svn://example.com/x",\n' |
| 126 # This foo/dir1/dir2 points to a different url than the one in bar. |
132 ' "foo/dir1/dir2": "/dir1/another",\n' | 127 ' "foo/dir1/dir2": "/dir1/another",\n' |
133 '}') | 128 '}') |
134 | 129 |
135 obj = gclient.GClient.LoadCurrentConfig(options) | 130 obj = gclient.GClient.LoadCurrentConfig(options) |
136 self._check_requirements(obj.dependencies[0], {}) | 131 self._check_requirements(obj.dependencies[0], {}) |
137 self._check_requirements(obj.dependencies[1], {}) | 132 self._check_requirements(obj.dependencies[1], {}) |
138 obj.RunOnDeps('None', args) | 133 obj.RunOnDeps('None', args) |
139 # The trick here is to manually process the list to make sure it's out of | |
140 # order. | |
141 for i in obj.dependencies: | |
142 # pylint: disable=W0212 | |
143 i._dependencies.sort(key=lambda x: x.name, reverse=reverse) | |
144 actual = self._get_processed() | 134 actual = self._get_processed() |
145 # We don't care of the ordering of these items: | 135 first_3 = [ |
146 self.assertEquals( | 136 'svn://example.com/bar', |
147 ['svn://example.com/bar', 'svn://example.com/foo'], sorted(actual[0:2])) | 137 'svn://example.com/bar_empty', |
148 actual = actual[2:] | 138 'svn://example.com/foo', |
149 # Ordering may not be exact in case of parallel jobs. | 139 ] |
150 self.assertTrue( | 140 if jobs != 1: |
151 actual.index('svn://example.com/bar/dir1/dir2') > | 141 # We don't care of the ordering of these items except that bar must be |
152 actual.index('svn://example.com/foo/dir1')) | 142 # before bar/empty. |
153 actual.remove('svn://example.com/bar/dir1/dir2') | 143 self.assertTrue( |
154 | 144 actual.index('svn://example.com/bar') < |
155 # Ordering may not be exact in case of parallel jobs. | 145 actual.index('svn://example.com/bar_empty')) |
156 actual.remove('svn://example.com/bar_empty') | 146 self.assertEquals(first_3, sorted(actual[0:3])) |
| 147 else: |
| 148 self.assertEquals(first_3, actual[0:3]) |
157 self.assertEquals( | 149 self.assertEquals( |
158 [ | 150 [ |
159 'svn://example.com/foo/dir1', | 151 'svn://example.com/foo/dir1', |
| 152 'svn://example.com/bar/dir1/dir2', |
160 'svn://example.com/foo/dir1/dir2/dir3', | 153 'svn://example.com/foo/dir1/dir2/dir3', |
161 'svn://example.com/foo/dir1/dir2/dir3/dir4', | 154 'svn://example.com/foo/dir1/dir2/dir3/dir4', |
162 # TODO(maruel): This is probably wrong. | |
163 'svn://example.com/foo/dir1/dir2/dir3/dir4/dir1/another', | 155 'svn://example.com/foo/dir1/dir2/dir3/dir4/dir1/another', |
164 ], | 156 ], |
165 actual) | 157 actual[3:]) |
166 | 158 |
| 159 self.assertEquals(3, len(obj.dependencies)) |
| 160 self.assertEquals('bar', obj.dependencies[0].name) |
| 161 self.assertEquals('bar/empty', obj.dependencies[1].name) |
| 162 self.assertEquals('foo', obj.dependencies[2].name) |
167 self._check_requirements( | 163 self._check_requirements( |
168 obj.dependencies[0], | 164 obj.dependencies[0], |
169 { | 165 { |
170 'foo/dir1': ['foo'], | 166 'foo/dir1/dir2': ['bar', 'bar/empty', 'foo', 'foo/dir1'], |
171 'foo/dir1/dir2/dir3': ['foo', 'foo/dir1', 'foo/dir1/dir2'], | |
172 'foo/dir1/dir2/dir3/dir4': | |
173 ['foo', 'foo/dir1', 'foo/dir1/dir2', 'foo/dir1/dir2/dir3'], | |
174 'foo/dir1/dir2/dir5/dir6': | |
175 ['foo', 'foo/dir1', 'foo/dir1/dir2', 'foo/dir1/dir2/dir3/dir4'], | |
176 }) | 167 }) |
177 self._check_requirements( | 168 self._check_requirements( |
178 obj.dependencies[1], | 169 obj.dependencies[1], |
| 170 {}) |
| 171 self._check_requirements( |
| 172 obj.dependencies[2], |
179 { | 173 { |
180 'foo/dir1/dir2': ['bar', 'foo', 'foo/dir1'], | 174 'foo/dir1': ['bar', 'bar/empty', 'foo'], |
| 175 'foo/dir1/dir2/dir3': |
| 176 ['bar', 'bar/empty', 'foo', 'foo/dir1', 'foo/dir1/dir2'], |
| 177 'foo/dir1/dir2/dir3/dir4': |
| 178 [ 'bar', 'bar/empty', 'foo', 'foo/dir1', 'foo/dir1/dir2', |
| 179 'foo/dir1/dir2/dir3'], |
| 180 'foo/dir1/dir2/dir5/dir6': |
| 181 [ 'bar', 'bar/empty', 'foo', 'foo/dir1', 'foo/dir1/dir2', |
| 182 'foo/dir1/dir2/dir3/dir4'], |
181 }) | 183 }) |
182 self._check_requirements( | 184 self._check_requirements( |
183 obj, | 185 obj, |
184 { | 186 { |
185 'foo': [], | 187 'foo': [], |
186 'bar': [], | 188 'bar': [], |
187 'bar/empty': ['bar'], | 189 'bar/empty': ['bar'], |
188 }) | 190 }) |
189 | 191 |
190 def _check_requirements(self, solution, expected): | 192 def _check_requirements(self, solution, expected): |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 gclient.Dependency( | 238 gclient.Dependency( |
237 obj.dependencies[0], 'foo/dir3', | 239 obj.dependencies[0], 'foo/dir3', |
238 gclient.GClientKeywords.FileImpl('url'), None, None, None, None, | 240 gclient.GClientKeywords.FileImpl('url'), None, None, None, None, |
239 'DEPS', True), | 241 'DEPS', True), |
240 ], | 242 ], |
241 []) | 243 []) |
242 # Make sure __str__() works fine. | 244 # Make sure __str__() works fine. |
243 # pylint: disable=W0212 | 245 # pylint: disable=W0212 |
244 obj.dependencies[0]._file_list.append('foo') | 246 obj.dependencies[0]._file_list.append('foo') |
245 str_obj = str(obj) | 247 str_obj = str(obj) |
246 self.assertEquals(472, len(str_obj), '%d\n%s' % (len(str_obj), str_obj)) | 248 self.assertEquals(471, len(str_obj), '%d\n%s' % (len(str_obj), str_obj)) |
247 | 249 |
248 | 250 |
249 if __name__ == '__main__': | 251 if __name__ == '__main__': |
250 sys.stdout = gclient_utils.MakeFileAutoFlush(sys.stdout) | 252 sys.stdout = gclient_utils.MakeFileAutoFlush(sys.stdout) |
251 sys.stdout = gclient_utils.MakeFileAnnotated(sys.stdout, include_zero=True) | 253 sys.stdout = gclient_utils.MakeFileAnnotated(sys.stdout, include_zero=True) |
252 sys.stderr = gclient_utils.MakeFileAutoFlush(sys.stderr) | 254 sys.stderr = gclient_utils.MakeFileAutoFlush(sys.stderr) |
253 sys.stderr = gclient_utils.MakeFileAnnotated(sys.stderr, include_zero=True) | 255 sys.stderr = gclient_utils.MakeFileAnnotated(sys.stderr, include_zero=True) |
254 logging.basicConfig( | 256 logging.basicConfig( |
255 level=[logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG][ | 257 level=[logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG][ |
256 min(sys.argv.count('-v'), 3)], | 258 min(sys.argv.count('-v'), 3)], |
257 format='%(relativeCreated)4d %(levelname)5s %(module)13s(' | 259 format='%(relativeCreated)4d %(levelname)5s %(module)13s(' |
258 '%(lineno)d) %(message)s') | 260 '%(lineno)d) %(message)s') |
259 unittest.main() | 261 unittest.main() |
OLD | NEW |