| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2010 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 """Smoke tests for gclient.py. | 6 """Smoke tests for gclient.py. |
| 7 | 7 |
| 8 Shell out 'gclient' and run basic conformance tests. | 8 Shell out 'gclient' and run basic conformance tests. |
| 9 | 9 |
| 10 This test assumes GClientSmokeBase.URL_BASE is valid. | 10 This test assumes GClientSmokeBase.URL_BASE is valid. |
| 11 """ | 11 """ |
| 12 | 12 |
| 13 import logging | 13 import logging |
| 14 import os | 14 import os |
| 15 import pprint | |
| 16 import re | 15 import re |
| 17 import shutil | |
| 18 import subprocess | 16 import subprocess |
| 19 import sys | 17 import sys |
| 20 import unittest | 18 import unittest |
| 21 | 19 |
| 22 from fake_repos import rmtree, write, FakeRepos | 20 from fake_repos import join, mangle_svn_tree, mangle_git_tree, write |
| 21 from fake_repos import FakeReposTestBase |
| 23 | 22 |
| 24 join = os.path.join | 23 GCLIENT_PATH = join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), |
| 25 | 24 'gclient') |
| 26 SHOULD_LEAK = False | 25 COVERAGE = False |
| 27 UNITTEST_DIR = os.path.abspath(os.path.dirname(__file__)) | |
| 28 GCLIENT_PATH = join(os.path.dirname(UNITTEST_DIR), 'gclient') | |
| 29 # all tests outputs goes there. | |
| 30 TRIAL_DIR = join(UNITTEST_DIR, '_trial') | |
| 31 # In case you want to use another machine to create the fake repos, e.g. | |
| 32 # not on Windows. | |
| 33 HOST = '127.0.0.1' | |
| 34 FAKE = None | |
| 35 | 26 |
| 36 | 27 |
| 37 def read_tree(tree_root): | 28 class GClientSmokeBase(FakeReposTestBase): |
| 38 """Returns a dict of all the files in a tree.""" | |
| 39 tree = {} | |
| 40 for root, dirs, files in os.walk(tree_root): | |
| 41 for d in filter(lambda x: x.startswith('.'), dirs): | |
| 42 dirs.remove(d) | |
| 43 for f in [join(root, f) for f in files if not f.startswith('.')]: | |
| 44 tree[f[len(tree_root) + 1:]] = open(join(root, f), 'rb').read() | |
| 45 return tree | |
| 46 | |
| 47 | |
| 48 def dict_diff(dict1, dict2): | |
| 49 diff = {} | |
| 50 for k, v in dict1.iteritems(): | |
| 51 if k not in dict2: | |
| 52 diff[k] = v | |
| 53 elif v != dict2[k]: | |
| 54 diff[k] = (v, dict2[k]) | |
| 55 for k, v in dict2.iteritems(): | |
| 56 if k not in dict1: | |
| 57 diff[k] = v | |
| 58 return diff | |
| 59 | |
| 60 | |
| 61 def mangle_svn_tree(*args): | |
| 62 result = {} | |
| 63 for old_root, new_root, tree in args: | |
| 64 for k, v in tree.iteritems(): | |
| 65 if not k.startswith(old_root): | |
| 66 continue | |
| 67 result[join(new_root, k[len(old_root) + 1:])] = v | |
| 68 return result | |
| 69 | |
| 70 | |
| 71 def mangle_git_tree(*args): | |
| 72 result = {} | |
| 73 for new_root, tree in args: | |
| 74 for k, v in tree.iteritems(): | |
| 75 result[join(new_root, k)] = v | |
| 76 return result | |
| 77 | |
| 78 | |
| 79 class GClientSmokeBase(unittest.TestCase): | |
| 80 # This subversion repository contains a test repository. | |
| 81 ROOT_DIR = join(TRIAL_DIR, 'smoke') | |
| 82 | |
| 83 def setUp(self): | 29 def setUp(self): |
| 84 # Vaguely inspired by twisted. | 30 FakeReposTestBase.setUp(self) |
| 85 # Make sure it doesn't try to auto update when testing! | 31 # Make sure it doesn't try to auto update when testing! |
| 86 self.env = os.environ.copy() | 32 self.env = os.environ.copy() |
| 87 self.env['DEPOT_TOOLS_UPDATE'] = '0' | 33 self.env['DEPOT_TOOLS_UPDATE'] = '0' |
| 88 # Remove left overs | |
| 89 self.root_dir = join(self.ROOT_DIR, self.id()) | |
| 90 rmtree(self.root_dir) | |
| 91 if not os.path.exists(self.ROOT_DIR): | |
| 92 os.mkdir(self.ROOT_DIR) | |
| 93 os.mkdir(self.root_dir) | |
| 94 self.svn_base = 'svn://%s/svn/' % HOST | |
| 95 self.git_base = 'git://%s/git/' % HOST | |
| 96 | |
| 97 def tearDown(self): | |
| 98 if not SHOULD_LEAK: | |
| 99 rmtree(self.root_dir) | |
| 100 | 34 |
| 101 def gclient(self, cmd, cwd=None): | 35 def gclient(self, cmd, cwd=None): |
| 102 if not cwd: | 36 if not cwd: |
| 103 cwd = self.root_dir | 37 cwd = self.root_dir |
| 104 process = subprocess.Popen([GCLIENT_PATH] + cmd, cwd=cwd, env=self.env, | 38 if COVERAGE: |
| 105 stdout=subprocess.PIPE, stderr=subprocess.PIPE, | 39 # Don't use the wrapper script. |
| 106 shell=sys.platform.startswith('win')) | 40 cmd_base = ['coverage', 'run', '-a', GCLIENT_PATH + '.py'] |
| 41 else: |
| 42 cmd_base = [GCLIENT_PATH] |
| 43 process = subprocess.Popen(cmd_base + cmd, cwd=cwd, env=self.env, |
| 44 stdout=subprocess.PIPE, stderr=subprocess.PIPE, |
| 45 shell=sys.platform.startswith('win')) |
| 107 (stdout, stderr) = process.communicate() | 46 (stdout, stderr) = process.communicate() |
| 108 return (stdout, stderr, process.returncode) | 47 return (stdout, stderr, process.returncode) |
| 109 | 48 |
| 110 def checkString(self, expected, result): | |
| 111 if expected != result: | |
| 112 # Strip the begining | |
| 113 while expected and result and expected[0] == result[0]: | |
| 114 expected = expected[1:] | |
| 115 result = result[1:] | |
| 116 # The exception trace makes it hard to read so dump it too. | |
| 117 if '\n' in result: | |
| 118 print result | |
| 119 self.assertEquals(expected, result) | |
| 120 | |
| 121 def check(self, expected, results): | |
| 122 self.checkString(expected[0], results[0]) | |
| 123 self.checkString(expected[1], results[1]) | |
| 124 self.assertEquals(expected[2], results[2]) | |
| 125 | |
| 126 def assertTree(self, tree): | |
| 127 actual = read_tree(self.root_dir) | |
| 128 diff = dict_diff(tree, actual) | |
| 129 if diff: | |
| 130 logging.debug('Actual %s\n%s' % (self.root_dir, pprint.pformat(actual))) | |
| 131 logging.debug('Expected\n%s' % pprint.pformat(tree)) | |
| 132 logging.debug('Diff\n%s' % pprint.pformat(diff)) | |
| 133 self.assertEquals(tree, actual) | |
| 134 | |
| 135 | 49 |
| 136 class GClientSmoke(GClientSmokeBase): | 50 class GClientSmoke(GClientSmokeBase): |
| 137 def testHelp(self): | 51 def testHelp(self): |
| 138 """testHelp: make sure no new command was added.""" | 52 """testHelp: make sure no new command was added.""" |
| 139 result = self.gclient(['help']) | 53 result = self.gclient(['help']) |
| 140 self.assertEquals(1197, len(result[0])) | 54 self.assertEquals(1197, len(result[0])) |
| 141 self.assertEquals(0, len(result[1])) | 55 self.assertEquals(0, len(result[1])) |
| 142 self.assertEquals(0, result[2]) | 56 self.assertEquals(0, result[2]) |
| 143 | 57 |
| 144 def testUnknown(self): | 58 def testUnknown(self): |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 os.remove(p) | 115 os.remove(p) |
| 202 results = self.gclient(['config', 'foo', 'faa', 'fuu']) | 116 results = self.gclient(['config', 'foo', 'faa', 'fuu']) |
| 203 err = ('Usage: gclient.py config [options] [url] [safesync url]\n\n' | 117 err = ('Usage: gclient.py config [options] [url] [safesync url]\n\n' |
| 204 'gclient.py: error: Inconsistent arguments. Use either --spec or one' | 118 'gclient.py: error: Inconsistent arguments. Use either --spec or one' |
| 205 ' or 2 args\n') | 119 ' or 2 args\n') |
| 206 self.check(('', err, 2), results) | 120 self.check(('', err, 2), results) |
| 207 self.assertFalse(os.path.exists(join(self.root_dir, '.gclient'))) | 121 self.assertFalse(os.path.exists(join(self.root_dir, '.gclient'))) |
| 208 | 122 |
| 209 | 123 |
| 210 class GClientSmokeSVN(GClientSmokeBase): | 124 class GClientSmokeSVN(GClientSmokeBase): |
| 125 def setUp(self): |
| 126 GClientSmokeBase.setUp(self) |
| 127 self.FAKE_REPOS.setUpSVN() |
| 128 |
| 211 def testSync(self): | 129 def testSync(self): |
| 212 # TODO(maruel): safesync, multiple solutions, invalid@revisions, | 130 # TODO(maruel): safesync, multiple solutions, invalid@revisions, |
| 213 # multiple revisions. | 131 # multiple revisions. |
| 214 self.gclient(['config', self.svn_base + 'trunk/src/']) | 132 self.gclient(['config', self.svn_base + 'trunk/src/']) |
| 215 # Test unversioned checkout. | 133 # Test unversioned checkout. |
| 216 results = self.gclient(['sync', '--deps', 'mac']) | 134 results = self.gclient(['sync', '--deps', 'mac']) |
| 217 logging.debug(results[0]) | 135 logging.debug(results[0]) |
| 218 out = results[0].splitlines(False) | 136 out = results[0].splitlines(False) |
| 219 self.assertEquals(17, len(out)) | 137 self.assertEquals(17, len(out)) |
| 220 self.checkString('', results[1]) | 138 self.checkString('', results[1]) |
| 221 self.assertEquals(0, results[2]) | 139 self.assertEquals(0, results[2]) |
| 222 tree = mangle_svn_tree( | 140 tree = mangle_svn_tree( |
| 223 (join('trunk', 'src'), 'src', FAKE.svn_revs[-1]), | 141 (join('trunk', 'src'), 'src', self.FAKE_REPOS.svn_revs[-1]), |
| 224 (join('trunk', 'third_party', 'foo'), join('src', 'third_party', 'foo'), | 142 (join('trunk', 'third_party', 'foo'), join('src', 'third_party', 'foo'), |
| 225 FAKE.svn_revs[1]), | 143 self.FAKE_REPOS.svn_revs[1]), |
| 226 (join('trunk', 'other'), join('src', 'other'), FAKE.svn_revs[2]), | 144 (join('trunk', 'other'), join('src', 'other'), |
| 145 self.FAKE_REPOS.svn_revs[2]), |
| 227 ) | 146 ) |
| 228 tree[join('src', 'hooked1')] = 'hooked1' | 147 tree[join('src', 'hooked1')] = 'hooked1' |
| 229 self.assertTree(tree) | 148 self.assertTree(tree) |
| 230 | 149 |
| 231 # Manually remove hooked1 before synching to make sure it's not recreated. | 150 # Manually remove hooked1 before synching to make sure it's not recreated. |
| 232 os.remove(join(self.root_dir, 'src', 'hooked1')) | 151 os.remove(join(self.root_dir, 'src', 'hooked1')) |
| 233 | 152 |
| 234 # Test incremental versioned sync: sync backward. | 153 # Test incremental versioned sync: sync backward. |
| 235 results = self.gclient(['sync', '--revision', 'src@1', '--deps', 'mac', | 154 results = self.gclient(['sync', '--revision', 'src@1', '--deps', 'mac', |
| 236 '--delete_unversioned_trees']) | 155 '--delete_unversioned_trees']) |
| 237 logging.debug(results[0]) | 156 logging.debug(results[0]) |
| 238 out = results[0].splitlines(False) | 157 out = results[0].splitlines(False) |
| 239 self.assertEquals(19, len(out)) | 158 self.assertEquals(19, len(out)) |
| 240 self.checkString('', results[1]) | 159 self.checkString('', results[1]) |
| 241 self.assertEquals(0, results[2]) | 160 self.assertEquals(0, results[2]) |
| 242 tree = mangle_svn_tree( | 161 tree = mangle_svn_tree( |
| 243 (join('trunk', 'src'), 'src', FAKE.svn_revs[1]), | 162 (join('trunk', 'src'), 'src', self.FAKE_REPOS.svn_revs[1]), |
| 244 (join('trunk', 'third_party', 'foo'), join('src', 'third_party', 'fpp'), | 163 (join('trunk', 'third_party', 'foo'), join('src', 'third_party', 'fpp'), |
| 245 FAKE.svn_revs[2]), | 164 self.FAKE_REPOS.svn_revs[2]), |
| 246 (join('trunk', 'other'), join('src', 'other'), FAKE.svn_revs[2]), | 165 (join('trunk', 'other'), join('src', 'other'), |
| 166 self.FAKE_REPOS.svn_revs[2]), |
| 247 (join('trunk', 'third_party', 'foo'), | 167 (join('trunk', 'third_party', 'foo'), |
| 248 join('src', 'third_party', 'prout'), | 168 join('src', 'third_party', 'prout'), |
| 249 FAKE.svn_revs[2]), | 169 self.FAKE_REPOS.svn_revs[2]), |
| 250 ) | 170 ) |
| 251 self.assertTree(tree) | 171 self.assertTree(tree) |
| 252 # Test incremental sync: delete-unversioned_trees isn't there. | 172 # Test incremental sync: delete-unversioned_trees isn't there. |
| 253 results = self.gclient(['sync', '--deps', 'mac']) | 173 results = self.gclient(['sync', '--deps', 'mac']) |
| 254 logging.debug(results[0]) | 174 logging.debug(results[0]) |
| 255 out = results[0].splitlines(False) | 175 out = results[0].splitlines(False) |
| 256 self.assertEquals(21, len(out)) | 176 self.assertEquals(21, len(out)) |
| 257 self.checkString('', results[1]) | 177 self.checkString('', results[1]) |
| 258 self.assertEquals(0, results[2]) | 178 self.assertEquals(0, results[2]) |
| 259 tree = mangle_svn_tree( | 179 tree = mangle_svn_tree( |
| 260 (join('trunk', 'src'), 'src', FAKE.svn_revs[-1]), | 180 (join('trunk', 'src'), 'src', self.FAKE_REPOS.svn_revs[-1]), |
| 261 (join('trunk', 'third_party', 'foo'), join('src', 'third_party', 'fpp'), | 181 (join('trunk', 'third_party', 'foo'), join('src', 'third_party', 'fpp'), |
| 262 FAKE.svn_revs[2]), | 182 self.FAKE_REPOS.svn_revs[2]), |
| 263 (join('trunk', 'third_party', 'foo'), join('src', 'third_party', 'foo'), | 183 (join('trunk', 'third_party', 'foo'), join('src', 'third_party', 'foo'), |
| 264 FAKE.svn_revs[1]), | 184 self.FAKE_REPOS.svn_revs[1]), |
| 265 (join('trunk', 'other'), join('src', 'other'), FAKE.svn_revs[2]), | 185 (join('trunk', 'other'), join('src', 'other'), |
| 186 self.FAKE_REPOS.svn_revs[2]), |
| 266 (join('trunk', 'third_party', 'foo'), | 187 (join('trunk', 'third_party', 'foo'), |
| 267 join('src', 'third_party', 'prout'), | 188 join('src', 'third_party', 'prout'), |
| 268 FAKE.svn_revs[2]), | 189 self.FAKE_REPOS.svn_revs[2]), |
| 269 ) | 190 ) |
| 270 tree[join('src', 'hooked1')] = 'hooked1' | 191 tree[join('src', 'hooked1')] = 'hooked1' |
| 271 self.assertTree(tree) | 192 self.assertTree(tree) |
| 272 | 193 |
| 273 def testRevertAndStatus(self): | 194 def testRevertAndStatus(self): |
| 274 self.gclient(['config', self.svn_base + 'trunk/src/']) | 195 self.gclient(['config', self.svn_base + 'trunk/src/']) |
| 275 # Tested in testSync. | 196 # Tested in testSync. |
| 276 self.gclient(['sync', '--deps', 'mac']) | 197 self.gclient(['sync', '--deps', 'mac']) |
| 277 write(join(self.root_dir, 'src', 'other', 'hi'), 'Hey!') | 198 write(join(self.root_dir, 'src', 'other', 'hi'), 'Hey!') |
| 278 | 199 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 291 self.assertEquals(0, results[2]) | 212 self.assertEquals(0, results[2]) |
| 292 | 213 |
| 293 # Revert implies --force implies running hooks without looking at pattern | 214 # Revert implies --force implies running hooks without looking at pattern |
| 294 # matching. | 215 # matching. |
| 295 results = self.gclient(['revert']) | 216 results = self.gclient(['revert']) |
| 296 out = results[0].splitlines(False) | 217 out = results[0].splitlines(False) |
| 297 self.assertEquals(22, len(out)) | 218 self.assertEquals(22, len(out)) |
| 298 self.checkString('', results[1]) | 219 self.checkString('', results[1]) |
| 299 self.assertEquals(0, results[2]) | 220 self.assertEquals(0, results[2]) |
| 300 tree = mangle_svn_tree( | 221 tree = mangle_svn_tree( |
| 301 (join('trunk', 'src'), 'src', FAKE.svn_revs[-1]), | 222 (join('trunk', 'src'), 'src', self.FAKE_REPOS.svn_revs[-1]), |
| 302 (join('trunk', 'third_party', 'foo'), join('src', 'third_party', 'foo'), | 223 (join('trunk', 'third_party', 'foo'), join('src', 'third_party', 'foo'), |
| 303 FAKE.svn_revs[1]), | 224 self.FAKE_REPOS.svn_revs[1]), |
| 304 (join('trunk', 'other'), join('src', 'other'), FAKE.svn_revs[2]), | 225 (join('trunk', 'other'), join('src', 'other'), |
| 226 self.FAKE_REPOS.svn_revs[2]), |
| 305 ) | 227 ) |
| 306 tree[join('src', 'hooked1')] = 'hooked1' | 228 tree[join('src', 'hooked1')] = 'hooked1' |
| 307 tree[join('src', 'hooked2')] = 'hooked2' | 229 tree[join('src', 'hooked2')] = 'hooked2' |
| 308 self.assertTree(tree) | 230 self.assertTree(tree) |
| 309 | 231 |
| 310 results = self.gclient(['status']) | 232 results = self.gclient(['status']) |
| 311 out = results[0].splitlines(False) | 233 out = results[0].splitlines(False) |
| 312 self.assertEquals(out[0], '') | 234 self.assertEquals(out[0], '') |
| 313 self.assertTrue(out[1].startswith('________ running \'svn status\' in \'')) | 235 self.assertTrue(out[1].startswith('________ running \'svn status\' in \'')) |
| 314 self.assertEquals(out[2], '? other') | 236 self.assertEquals(out[2], '? other') |
| (...skipping 25 matching lines...) Expand all Loading... |
| 340 self.assertEquals(0, results[2]) | 262 self.assertEquals(0, results[2]) |
| 341 | 263 |
| 342 # Revert implies --force implies running hooks without looking at pattern | 264 # Revert implies --force implies running hooks without looking at pattern |
| 343 # matching. | 265 # matching. |
| 344 results = self.gclient(['revert', '--deps', 'mac']) | 266 results = self.gclient(['revert', '--deps', 'mac']) |
| 345 out = results[0].splitlines(False) | 267 out = results[0].splitlines(False) |
| 346 self.assertEquals(24, len(out)) | 268 self.assertEquals(24, len(out)) |
| 347 self.checkString('', results[1]) | 269 self.checkString('', results[1]) |
| 348 self.assertEquals(0, results[2]) | 270 self.assertEquals(0, results[2]) |
| 349 tree = mangle_svn_tree( | 271 tree = mangle_svn_tree( |
| 350 (join('trunk', 'src'), 'src', FAKE.svn_revs[1]), | 272 (join('trunk', 'src'), 'src', self.FAKE_REPOS.svn_revs[1]), |
| 351 (join('trunk', 'third_party', 'foo'), join('src', 'third_party', 'fpp'), | 273 (join('trunk', 'third_party', 'foo'), join('src', 'third_party', 'fpp'), |
| 352 FAKE.svn_revs[2]), | 274 self.FAKE_REPOS.svn_revs[2]), |
| 353 (join('trunk', 'other'), join('src', 'other'), FAKE.svn_revs[2]), | 275 (join('trunk', 'other'), join('src', 'other'), |
| 276 self.FAKE_REPOS.svn_revs[2]), |
| 354 (join('trunk', 'third_party', 'prout'), | 277 (join('trunk', 'third_party', 'prout'), |
| 355 join('src', 'third_party', 'prout'), | 278 join('src', 'third_party', 'prout'), |
| 356 FAKE.svn_revs[2]), | 279 self.FAKE_REPOS.svn_revs[2]), |
| 357 ) | 280 ) |
| 358 self.assertTree(tree) | 281 self.assertTree(tree) |
| 359 | 282 |
| 360 results = self.gclient(['status', '--deps', 'mac']) | 283 results = self.gclient(['status', '--deps', 'mac']) |
| 361 out = results[0].splitlines(False) | 284 out = results[0].splitlines(False) |
| 362 self.assertEquals(out[0], '') | 285 self.assertEquals(out[0], '') |
| 363 self.assertTrue(out[1].startswith('________ running \'svn status\' in \'')) | 286 self.assertTrue(out[1].startswith('________ running \'svn status\' in \'')) |
| 364 self.assertEquals(out[2], '? other') | 287 self.assertEquals(out[2], '? other') |
| 365 self.assertEquals(out[3], '? third_party/fpp') | 288 self.assertEquals(out[3], '? third_party/fpp') |
| 366 self.assertEquals(out[4], '? third_party/prout') | 289 self.assertEquals(out[4], '? third_party/prout') |
| (...skipping 12 matching lines...) Expand all Loading... |
| 379 r'open\(\'src/hooked1\', \'w\'\)\.write\(\'hooked1\'\)\' in \'.*', | 302 r'open\(\'src/hooked1\', \'w\'\)\.write\(\'hooked1\'\)\' in \'.*', |
| 380 out[1])) | 303 out[1])) |
| 381 self.assertEquals(out[2], '') | 304 self.assertEquals(out[2], '') |
| 382 # runhooks runs all hooks even if not matching by design. | 305 # runhooks runs all hooks even if not matching by design. |
| 383 self.assertTrue(re.match(r'^________ running \'.*?python -c ' | 306 self.assertTrue(re.match(r'^________ running \'.*?python -c ' |
| 384 r'open\(\'src/hooked2\', \'w\'\)\.write\(\'hooked2\'\)\' in \'.*', | 307 r'open\(\'src/hooked2\', \'w\'\)\.write\(\'hooked2\'\)\' in \'.*', |
| 385 out[3])) | 308 out[3])) |
| 386 self.checkString('', results[1]) | 309 self.checkString('', results[1]) |
| 387 self.assertEquals(0, results[2]) | 310 self.assertEquals(0, results[2]) |
| 388 | 311 |
| 389 def testRunHooks(self): | |
| 390 self.gclient(['config', self.svn_base + 'trunk/src/']) | |
| 391 self.gclient(['sync', '--deps', 'mac']) | |
| 392 results = self.gclient(['runhooks']) | |
| 393 out = results[0].splitlines(False) | |
| 394 self.assertEquals(4, len(out)) | |
| 395 self.assertEquals(out[0], '') | |
| 396 self.assertTrue(re.match(r'^________ running \'.*?python -c ' | |
| 397 r'open\(\'src/hooked1\', \'w\'\)\.write\(\'hooked1\'\)\' in \'.*', | |
| 398 out[1])) | |
| 399 self.assertEquals(out[2], '') | |
| 400 # runhooks runs all hooks even if not matching by design. | |
| 401 self.assertTrue(re.match(r'^________ running \'.*?python -c ' | |
| 402 r'open\(\'src/hooked2\', \'w\'\)\.write\(\'hooked2\'\)\' in \'.*', | |
| 403 out[3])) | |
| 404 self.checkString('', results[1]) | |
| 405 self.assertEquals(0, results[2]) | |
| 406 | |
| 407 def testRunHooksDepsOs(self): | 312 def testRunHooksDepsOs(self): |
| 408 self.gclient(['config', self.svn_base + 'trunk/src/']) | 313 self.gclient(['config', self.svn_base + 'trunk/src/']) |
| 409 self.gclient(['sync', '--deps', 'mac', '--revision', 'src@1']) | 314 self.gclient(['sync', '--deps', 'mac', '--revision', 'src@1']) |
| 410 results = self.gclient(['runhooks']) | 315 results = self.gclient(['runhooks']) |
| 411 self.check(('', '', 0), results) | 316 self.check(('', '', 0), results) |
| 412 | 317 |
| 413 def testRevInfo(self): | 318 def testRevInfo(self): |
| 414 # TODO(maruel): Test multiple solutions. | 319 # TODO(maruel): Test multiple solutions. |
| 415 self.gclient(['config', self.svn_base + 'trunk/src/']) | 320 self.gclient(['config', self.svn_base + 'trunk/src/']) |
| 416 self.gclient(['sync', '--deps', 'mac']) | 321 self.gclient(['sync', '--deps', 'mac']) |
| 417 results = self.gclient(['revinfo']) | 322 results = self.gclient(['revinfo']) |
| 418 out = ('src: %(base)s/src@2;\n' | 323 out = ('src: %(base)s/src@2;\n' |
| 419 'src/other: %(base)s/other@2;\n' | 324 'src/other: %(base)s/other@2;\n' |
| 420 'src/third_party/foo: %(base)s/third_party/foo@1\n' % | 325 'src/third_party/foo: %(base)s/third_party/foo@1\n' % |
| 421 { 'base': self.svn_base + 'trunk' }) | 326 { 'base': self.svn_base + 'trunk' }) |
| 422 self.check((out, '', 0), results) | 327 self.check((out, '', 0), results) |
| 423 | 328 |
| 424 | 329 |
| 425 class GClientSmokeGIT(GClientSmokeBase): | 330 class GClientSmokeGIT(GClientSmokeBase): |
| 331 def setUp(self): |
| 332 GClientSmokeBase.setUp(self) |
| 333 self.FAKE_REPOS.setUpGIT() |
| 334 |
| 426 def testSync(self): | 335 def testSync(self): |
| 427 # TODO(maruel): safesync, multiple solutions, invalid@revisions, | 336 # TODO(maruel): safesync, multiple solutions, invalid@revisions, |
| 428 # multiple revisions. | 337 # multiple revisions. |
| 429 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) | 338 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) |
| 430 # Test unversioned checkout. | 339 # Test unversioned checkout. |
| 431 results = self.gclient(['sync', '--deps', 'mac']) | 340 results = self.gclient(['sync', '--deps', 'mac']) |
| 432 out = results[0].splitlines(False) | 341 out = results[0].splitlines(False) |
| 433 # TODO(maruel): http://crosbug.com/3582 hooks run even if not matching, must | 342 # TODO(maruel): http://crosbug.com/3582 hooks run even if not matching, must |
| 434 # add sync parsing to get the list of updated files. | 343 # add sync parsing to get the list of updated files. |
| 435 self.assertEquals(13, len(out)) | 344 self.assertEquals(13, len(out)) |
| 436 self.assertTrue(results[1].startswith('Switched to a new branch \'')) | 345 self.assertTrue(results[1].startswith('Switched to a new branch \'')) |
| 437 self.assertEquals(0, results[2]) | 346 self.assertEquals(0, results[2]) |
| 438 tree = mangle_git_tree( | 347 tree = mangle_git_tree( |
| 439 ('src', FAKE.git_hashes['repo_1'][1][1]), | 348 ('src', self.FAKE_REPOS.git_hashes['repo_1'][1][1]), |
| 440 (join('src', 'repo2'), FAKE.git_hashes['repo_2'][0][1]), | 349 (join('src', 'repo2'), self.FAKE_REPOS.git_hashes['repo_2'][0][1]), |
| 441 (join('src', 'repo2', 'repo_renamed'), FAKE.git_hashes['repo_3'][1][1]), | 350 (join('src', 'repo2', 'repo_renamed'), |
| 351 self.FAKE_REPOS.git_hashes['repo_3'][1][1]), |
| 442 ) | 352 ) |
| 443 tree[join('src', 'hooked1')] = 'hooked1' | 353 tree[join('src', 'hooked1')] = 'hooked1' |
| 444 tree[join('src', 'hooked2')] = 'hooked2' | 354 tree[join('src', 'hooked2')] = 'hooked2' |
| 445 self.assertTree(tree) | 355 self.assertTree(tree) |
| 446 | 356 |
| 447 # Manually remove hooked1 before synching to make sure it's not recreated. | 357 # Manually remove hooked1 before synching to make sure it's not recreated. |
| 448 os.remove(join(self.root_dir, 'src', 'hooked1')) | 358 os.remove(join(self.root_dir, 'src', 'hooked1')) |
| 449 | 359 |
| 450 # Test incremental versioned sync: sync backward. | 360 # Test incremental versioned sync: sync backward. |
| 451 results = self.gclient(['sync', '--revision', | 361 results = self.gclient(['sync', '--revision', |
| 452 'src@' + FAKE.git_hashes['repo_1'][0][0], | 362 'src@' + self.FAKE_REPOS.git_hashes['repo_1'][0][0], |
| 453 '--deps', 'mac', '--delete_unversioned_trees']) | 363 '--deps', 'mac', '--delete_unversioned_trees']) |
| 454 logging.debug(results[0]) | 364 logging.debug(results[0]) |
| 455 out = results[0].splitlines(False) | 365 out = results[0].splitlines(False) |
| 456 self.assertEquals(20, len(out)) | 366 self.assertEquals(20, len(out)) |
| 457 self.checkString('', results[1]) | 367 self.checkString('', results[1]) |
| 458 self.assertEquals(0, results[2]) | 368 self.assertEquals(0, results[2]) |
| 459 tree = mangle_git_tree( | 369 tree = mangle_git_tree( |
| 460 ('src', FAKE.git_hashes['repo_1'][0][1]), | 370 ('src', self.FAKE_REPOS.git_hashes['repo_1'][0][1]), |
| 461 (join('src', 'repo2'), FAKE.git_hashes['repo_2'][1][1]), | 371 (join('src', 'repo2'), self.FAKE_REPOS.git_hashes['repo_2'][1][1]), |
| 462 (join('src', 'repo2', 'repo3'), FAKE.git_hashes['repo_3'][1][1]), | 372 (join('src', 'repo2', 'repo3'), |
| 463 (join('src', 'repo4'), FAKE.git_hashes['repo_4'][1][1]), | 373 self.FAKE_REPOS.git_hashes['repo_3'][1][1]), |
| 374 (join('src', 'repo4'), self.FAKE_REPOS.git_hashes['repo_4'][1][1]), |
| 464 ) | 375 ) |
| 465 tree[join('src', 'hooked2')] = 'hooked2' | 376 tree[join('src', 'hooked2')] = 'hooked2' |
| 466 self.assertTree(tree) | 377 self.assertTree(tree) |
| 467 # Test incremental sync: delete-unversioned_trees isn't there. | 378 # Test incremental sync: delete-unversioned_trees isn't there. |
| 468 results = self.gclient(['sync', '--deps', 'mac']) | 379 results = self.gclient(['sync', '--deps', 'mac']) |
| 469 logging.debug(results[0]) | 380 logging.debug(results[0]) |
| 470 out = results[0].splitlines(False) | 381 out = results[0].splitlines(False) |
| 471 self.assertEquals(25, len(out)) | 382 self.assertEquals(25, len(out)) |
| 472 self.checkString('', results[1]) | 383 self.checkString('', results[1]) |
| 473 self.assertEquals(0, results[2]) | 384 self.assertEquals(0, results[2]) |
| 474 tree = mangle_git_tree( | 385 tree = mangle_git_tree( |
| 475 ('src', FAKE.git_hashes['repo_1'][1][1]), | 386 ('src', self.FAKE_REPOS.git_hashes['repo_1'][1][1]), |
| 476 (join('src', 'repo2'), FAKE.git_hashes['repo_2'][1][1]), | 387 (join('src', 'repo2'), self.FAKE_REPOS.git_hashes['repo_2'][1][1]), |
| 477 (join('src', 'repo2', 'repo3'), FAKE.git_hashes['repo_3'][1][1]), | 388 (join('src', 'repo2', 'repo3'), |
| 478 (join('src', 'repo2', 'repo_renamed'), FAKE.git_hashes['repo_3'][1][1]), | 389 self.FAKE_REPOS.git_hashes['repo_3'][1][1]), |
| 479 (join('src', 'repo4'), FAKE.git_hashes['repo_4'][1][1]), | 390 (join('src', 'repo2', 'repo_renamed'), |
| 391 self.FAKE_REPOS.git_hashes['repo_3'][1][1]), |
| 392 (join('src', 'repo4'), self.FAKE_REPOS.git_hashes['repo_4'][1][1]), |
| 480 ) | 393 ) |
| 481 tree[join('src', 'hooked1')] = 'hooked1' | 394 tree[join('src', 'hooked1')] = 'hooked1' |
| 482 tree[join('src', 'hooked2')] = 'hooked2' | 395 tree[join('src', 'hooked2')] = 'hooked2' |
| 483 self.assertTree(tree) | 396 self.assertTree(tree) |
| 484 | 397 |
| 485 def testRevertAndStatus(self): | 398 def testRevertAndStatus(self): |
| 486 """TODO(maruel): Remove this line once this test is fixed.""" | 399 """TODO(maruel): Remove this line once this test is fixed.""" |
| 487 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) | 400 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) |
| 488 # Tested in testSync. | 401 # Tested in testSync. |
| 489 self.gclient(['sync', '--deps', 'mac']) | 402 self.gclient(['sync', '--deps', 'mac']) |
| 490 write(join(self.root_dir, 'src', 'repo2', 'hi'), 'Hey!') | 403 write(join(self.root_dir, 'src', 'repo2', 'hi'), 'Hey!') |
| 491 | 404 |
| 492 results = self.gclient(['status']) | 405 results = self.gclient(['status']) |
| 493 out = results[0].splitlines(False) | 406 out = results[0].splitlines(False) |
| 494 # TODO(maruel): http://crosbug.com/3584 It should output the unversioned | 407 # TODO(maruel): http://crosbug.com/3584 It should output the unversioned |
| 495 # files. | 408 # files. |
| 496 self.assertEquals(0, len(out)) | 409 self.assertEquals(0, len(out)) |
| 497 | 410 |
| 498 # Revert implies --force implies running hooks without looking at pattern | 411 # Revert implies --force implies running hooks without looking at pattern |
| 499 # matching. | 412 # matching. |
| 500 results = self.gclient(['revert']) | 413 results = self.gclient(['revert']) |
| 501 out = results[0].splitlines(False) | 414 out = results[0].splitlines(False) |
| 502 # TODO(maruel): http://crosbug.com/3583 It just runs the hooks right now. | 415 # TODO(maruel): http://crosbug.com/3583 It just runs the hooks right now. |
| 503 self.assertEquals(7, len(out)) | 416 self.assertEquals(7, len(out)) |
| 504 self.checkString('', results[1]) | 417 self.checkString('', results[1]) |
| 505 self.assertEquals(0, results[2]) | 418 self.assertEquals(0, results[2]) |
| 506 tree = mangle_git_tree( | 419 tree = mangle_git_tree( |
| 507 ('src', FAKE.git_hashes['repo_1'][1][1]), | 420 ('src', self.FAKE_REPOS.git_hashes['repo_1'][1][1]), |
| 508 (join('src', 'repo2'), FAKE.git_hashes['repo_2'][0][1]), | 421 (join('src', 'repo2'), self.FAKE_REPOS.git_hashes['repo_2'][0][1]), |
| 509 (join('src', 'repo2', 'repo_renamed'), FAKE.git_hashes['repo_3'][1][1]), | 422 (join('src', 'repo2', 'repo_renamed'), |
| 423 self.FAKE_REPOS.git_hashes['repo_3'][1][1]), |
| 510 ) | 424 ) |
| 511 # TODO(maruel): http://crosbug.com/3583 This file should have been removed. | 425 # TODO(maruel): http://crosbug.com/3583 This file should have been removed. |
| 512 tree[join('src', 'repo2', 'hi')] = 'Hey!' | 426 tree[join('src', 'repo2', 'hi')] = 'Hey!' |
| 513 tree[join('src', 'hooked1')] = 'hooked1' | 427 tree[join('src', 'hooked1')] = 'hooked1' |
| 514 tree[join('src', 'hooked2')] = 'hooked2' | 428 tree[join('src', 'hooked2')] = 'hooked2' |
| 515 self.assertTree(tree) | 429 self.assertTree(tree) |
| 516 | 430 |
| 517 results = self.gclient(['status']) | 431 results = self.gclient(['status']) |
| 518 out = results[0].splitlines(False) | 432 out = results[0].splitlines(False) |
| 519 # TODO(maruel): http://crosbug.com/3584 It should output the unversioned | 433 # TODO(maruel): http://crosbug.com/3584 It should output the unversioned |
| (...skipping 22 matching lines...) Expand all Loading... |
| 542 def testRevInfo(self): | 456 def testRevInfo(self): |
| 543 # TODO(maruel): Test multiple solutions. | 457 # TODO(maruel): Test multiple solutions. |
| 544 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) | 458 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) |
| 545 self.gclient(['sync', '--deps', 'mac']) | 459 self.gclient(['sync', '--deps', 'mac']) |
| 546 results = self.gclient(['revinfo']) | 460 results = self.gclient(['revinfo']) |
| 547 out = ('src: %(base)srepo_1@%(hash1)s;\n' | 461 out = ('src: %(base)srepo_1@%(hash1)s;\n' |
| 548 'src/repo2: %(base)srepo_2@%(hash2)s;\n' | 462 'src/repo2: %(base)srepo_2@%(hash2)s;\n' |
| 549 'src/repo2/repo_renamed: %(base)srepo_3@%(hash3)s\n' % | 463 'src/repo2/repo_renamed: %(base)srepo_3@%(hash3)s\n' % |
| 550 { | 464 { |
| 551 'base': self.git_base, | 465 'base': self.git_base, |
| 552 'hash1': FAKE.git_hashes['repo_1'][1][0], | 466 'hash1': self.FAKE_REPOS.git_hashes['repo_1'][1][0], |
| 553 'hash2': FAKE.git_hashes['repo_2'][0][0], | 467 'hash2': self.FAKE_REPOS.git_hashes['repo_2'][0][0], |
| 554 'hash3': FAKE.git_hashes['repo_3'][1][0], | 468 'hash3': self.FAKE_REPOS.git_hashes['repo_3'][1][0], |
| 555 }) | 469 }) |
| 556 self.check((out, '', 0), results) | 470 self.check((out, '', 0), results) |
| 557 | 471 |
| 558 | 472 |
| 559 if __name__ == '__main__': | 473 if __name__ == '__main__': |
| 560 if '-v' in sys.argv: | 474 if '-c' in sys.argv: |
| 561 logging.basicConfig(level=logging.DEBUG) | 475 COVERAGE = True |
| 562 if '-l' in sys.argv: | 476 sys.argv.remove('-c') |
| 563 SHOULD_LEAK = True | 477 if os.path.exists('.coverage'): |
| 564 sys.argv.remove('-l') | 478 os.remove('.coverage') |
| 565 FAKE = FakeRepos(TRIAL_DIR, SHOULD_LEAK, True) | 479 os.environ['COVERAGE_FILE'] = os.path.join( |
| 566 try: | 480 os.path.dirname(os.path.dirname(os.path.abspath(__file__))), |
| 567 FAKE.setUp() | 481 '.coverage') |
| 568 unittest.main() | 482 unittest.main() |
| 569 finally: | |
| 570 FAKE.tearDown() | |
| OLD | NEW |