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 |
| 11 from __future__ import with_statement |
11 import Queue | 12 import Queue |
12 import logging | 13 import logging |
13 import os | 14 import os |
14 import sys | 15 import sys |
15 import unittest | 16 import unittest |
16 | 17 |
17 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) | 18 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) |
18 sys.path.insert(0, os.path.dirname(BASE_DIR)) | 19 sys.path.insert(0, os.path.dirname(BASE_DIR)) |
19 | 20 |
20 import gclient | 21 import gclient |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 # fetched until 'src' is done. | 88 # fetched until 'src' is done. |
88 # jobs is the number of parallel jobs simulated. reverse is to reshuffle the | 89 # 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 # list to see if it is still processed in order correctly. |
90 parser = gclient.Parser() | 91 parser = gclient.Parser() |
91 options, args = parser.parse_args(['--jobs', jobs]) | 92 options, args = parser.parse_args(['--jobs', jobs]) |
92 write( | 93 write( |
93 '.gclient', | 94 '.gclient', |
94 'solutions = [\n' | 95 'solutions = [\n' |
95 ' { "name": "foo", "url": "svn://example.com/foo" },\n' | 96 ' { "name": "foo", "url": "svn://example.com/foo" },\n' |
96 ' { "name": "bar", "url": "svn://example.com/bar" },\n' | 97 ' { "name": "bar", "url": "svn://example.com/bar" },\n' |
| 98 ' { "name": "bar/empty", "url": "svn://example.com/bar_empty" },\n' |
97 ']') | 99 ']') |
98 write( | 100 write( |
99 os.path.join('foo', 'DEPS'), | 101 os.path.join('foo', 'DEPS'), |
100 'deps = {\n' | 102 'deps = {\n' |
101 ' "foo/dir1": "/dir1",\n' | 103 ' "foo/dir1": "/dir1",\n' |
102 ' "foo/dir1/dir2/dir3": "/dir1/dir2/dir3",\n' | 104 ' "foo/dir1/dir2/dir3": "/dir1/dir2/dir3",\n' |
103 ' "foo/dir1/dir4": "/dir1/dir4",\n' | 105 ' "foo/dir1/dir4": "/dir1/dir4",\n' |
104 ' "foo/dir1/dir2/dir3/dir4": "/dir1/dir2/dir3/dir4",\n' | 106 ' "foo/dir1/dir2/dir3/dir4": "/dir1/dir2/dir3/dir4",\n' |
105 '}') | 107 '}') |
106 write( | 108 write( |
107 os.path.join('bar', 'DEPS'), | 109 os.path.join('bar', 'DEPS'), |
108 'deps = {\n' | 110 'deps = {\n' |
109 ' "foo/dir1/dir2": "/dir1/dir2",\n' | 111 ' "foo/dir1/dir2": "/dir1/dir2",\n' |
110 '}') | 112 '}') |
| 113 write( |
| 114 os.path.join('bar/empty', 'DEPS'), |
| 115 'deps = {\n' |
| 116 '}') |
111 | 117 |
112 obj = gclient.GClient.LoadCurrentConfig(options) | 118 obj = gclient.GClient.LoadCurrentConfig(options) |
113 self._check_requirements(obj.dependencies[0], {}) | 119 self._check_requirements(obj.dependencies[0], {}) |
114 self._check_requirements(obj.dependencies[1], {}) | 120 self._check_requirements(obj.dependencies[1], {}) |
115 obj.RunOnDeps('None', args) | 121 obj.RunOnDeps('None', args) |
116 # The trick here is to manually process the list to make sure it's out of | 122 # The trick here is to manually process the list to make sure it's out of |
117 # order. | 123 # order. |
118 obj.dependencies[0].dependencies.sort(key=lambda x: x.name, reverse=reverse) | 124 for i in obj.dependencies: |
| 125 i.dependencies.sort(key=lambda x: x.name, reverse=reverse) |
119 actual = self._get_processed() | 126 actual = self._get_processed() |
120 # We don't care of the ordering of this item. | 127 # We don't care of the ordering of these items: |
| 128 self.assertEquals( |
| 129 ['svn://example.com/bar', 'svn://example.com/foo'], sorted(actual[0:2])) |
| 130 actual = actual[2:] |
| 131 # Ordering may not be exact in case of parallel jobs. |
| 132 self.assertTrue( |
| 133 actual.index('svn://example.com/bar/dir1/dir2') > |
| 134 actual.index('svn://example.com/foo/dir1')) |
121 actual.remove('svn://example.com/bar/dir1/dir2') | 135 actual.remove('svn://example.com/bar/dir1/dir2') |
| 136 |
| 137 # Ordering may not be exact in case of parallel jobs. |
| 138 actual.remove('svn://example.com/bar_empty') |
122 self.assertEquals( | 139 self.assertEquals( |
123 [ | 140 [ |
124 'svn://example.com/foo', | |
125 'svn://example.com/bar', | |
126 'svn://example.com/foo/dir1', | 141 'svn://example.com/foo/dir1', |
127 'svn://example.com/foo/dir1/dir4', | 142 'svn://example.com/foo/dir1/dir4', |
128 'svn://example.com/foo/dir1/dir2/dir3', | 143 'svn://example.com/foo/dir1/dir2/dir3', |
129 'svn://example.com/foo/dir1/dir2/dir3/dir4', | 144 'svn://example.com/foo/dir1/dir2/dir3/dir4', |
130 ], | 145 ], |
131 actual) | 146 actual) |
132 self._check_requirements( | 147 self._check_requirements( |
133 obj.dependencies[0], | 148 obj.dependencies[0], |
134 { | 149 { |
135 'foo/dir1': ['foo'], | 150 'foo/dir1': ['foo'], |
136 'foo/dir1/dir2/dir3': ['foo', 'foo/dir1'], | 151 'foo/dir1/dir2/dir3': ['foo', 'foo/dir1', 'foo/dir1/dir2'], |
137 'foo/dir1/dir2/dir3/dir4': ['foo', 'foo/dir1', 'foo/dir1/dir2/dir3'], | 152 'foo/dir1/dir2/dir3/dir4': |
| 153 ['foo', 'foo/dir1', 'foo/dir1/dir2', 'foo/dir1/dir2/dir3'], |
138 'foo/dir1/dir4': ['foo', 'foo/dir1'], | 154 'foo/dir1/dir4': ['foo', 'foo/dir1'], |
139 }) | 155 }) |
140 self._check_requirements( | 156 self._check_requirements( |
141 obj.dependencies[1], | 157 obj.dependencies[1], |
142 { | 158 { |
143 'foo/dir1/dir2': ['bar'], | 159 'foo/dir1/dir2': ['bar', 'foo', 'foo/dir1'], |
| 160 }) |
| 161 self._check_requirements( |
| 162 obj, |
| 163 { |
| 164 'foo': [], |
| 165 'bar': [], |
| 166 'bar/empty': ['bar'], |
144 }) | 167 }) |
145 | 168 |
146 def _check_requirements(self, solution, expected): | 169 def _check_requirements(self, solution, expected): |
147 for dependency in solution.dependencies: | 170 for dependency in solution.dependencies: |
148 self.assertEquals(expected.pop(dependency.name), dependency.requirements) | 171 self.assertEquals( |
| 172 expected.pop(dependency.name), sorted(dependency.requirements)) |
149 self.assertEquals({}, expected) | 173 self.assertEquals({}, expected) |
150 | 174 |
151 def _get_processed(self): | 175 def _get_processed(self): |
152 items = [] | 176 items = [] |
153 try: | 177 try: |
154 while True: | 178 while True: |
155 items.append(self.processed.get_nowait()) | 179 items.append(self.processed.get_nowait()) |
156 except Queue.Empty: | 180 except Queue.Empty: |
157 pass | 181 pass |
158 return items | 182 return items |
159 | 183 |
160 | 184 |
161 if __name__ == '__main__': | 185 if __name__ == '__main__': |
162 logging.basicConfig( | 186 logging.basicConfig( |
163 level=[logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG][ | 187 level=[logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG][ |
164 min(sys.argv.count('-v'), 3)], | 188 min(sys.argv.count('-v'), 3)], |
165 format='%(asctime).19s %(levelname)s %(filename)s:' | 189 format='%(asctime).19s %(levelname)s %(filename)s:' |
166 '%(lineno)s %(message)s') | 190 '%(lineno)s %(message)s') |
167 unittest.main() | 191 unittest.main() |
OLD | NEW |