| 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 |