| 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 re | 15 import re |
| 16 import subprocess | 16 import subprocess |
| 17 import sys | 17 import sys |
| 18 import unittest | 18 import unittest |
| 19 | 19 |
| 20 from fake_repos import join, mangle_svn_tree, mangle_git_tree, write | 20 from fake_repos import join, write, FakeReposTestBase |
| 21 from fake_repos import FakeReposTestBase | |
| 22 | 21 |
| 23 GCLIENT_PATH = join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), | 22 GCLIENT_PATH = join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), |
| 24 'gclient') | 23 'gclient') |
| 25 COVERAGE = False | 24 COVERAGE = False |
| 26 | 25 |
| 27 | 26 |
| 28 class GClientSmokeBase(FakeReposTestBase): | 27 class GClientSmokeBase(FakeReposTestBase): |
| 29 def setUp(self): | 28 def setUp(self): |
| 30 FakeReposTestBase.setUp(self) | 29 FakeReposTestBase.setUp(self) |
| 31 # Make sure it doesn't try to auto update when testing! | 30 # Make sure it doesn't try to auto update when testing! |
| 32 self.env = os.environ.copy() | 31 self.env = os.environ.copy() |
| 33 self.env['DEPOT_TOOLS_UPDATE'] = '0' | 32 self.env['DEPOT_TOOLS_UPDATE'] = '0' |
| 34 | 33 |
| 35 def gclient(self, cmd, cwd=None): | 34 def gclient(self, cmd, cwd=None): |
| 36 if not cwd: | 35 if not cwd: |
| 37 cwd = self.root_dir | 36 cwd = self.root_dir |
| 38 if COVERAGE: | 37 if COVERAGE: |
| 39 # Don't use the wrapper script. | 38 # Don't use the wrapper script. |
| 40 cmd_base = ['coverage', 'run', '-a', GCLIENT_PATH + '.py'] | 39 cmd_base = ['coverage', 'run', '-a', GCLIENT_PATH + '.py'] |
| 41 else: | 40 else: |
| 42 cmd_base = [GCLIENT_PATH] | 41 cmd_base = [GCLIENT_PATH] |
| 43 process = subprocess.Popen(cmd_base + cmd, cwd=cwd, env=self.env, | 42 cmd = cmd_base + cmd |
| 43 process = subprocess.Popen(cmd, cwd=cwd, env=self.env, |
| 44 stdout=subprocess.PIPE, stderr=subprocess.PIPE, | 44 stdout=subprocess.PIPE, stderr=subprocess.PIPE, |
| 45 shell=sys.platform.startswith('win')) | 45 shell=sys.platform.startswith('win')) |
| 46 (stdout, stderr) = process.communicate() | 46 (stdout, stderr) = process.communicate() |
| 47 logging.debug("XXX: %s\n%s\nXXX" % (' '.join(cmd), stdout)) |
| 47 return (stdout.replace('\r\n', '\n'), stderr.replace('\r\n', '\n'), | 48 return (stdout.replace('\r\n', '\n'), stderr.replace('\r\n', '\n'), |
| 48 process.returncode) | 49 process.returncode) |
| 49 | 50 |
| 51 def parseGclient(self, cmd, items): |
| 52 """Parse gclient's output to make it easier to test.""" |
| 53 (stdout, stderr, returncode) = self.gclient(cmd) |
| 54 self.checkString('', stderr) |
| 55 self.assertEquals(0, returncode) |
| 56 return self.checkBlock(stdout, items) |
| 57 |
| 58 def splitBlock(self, stdout): |
| 59 """Split gclient's output into logical execution blocks. |
| 60 ___ running 'foo' at '/bar' |
| 61 (...) |
| 62 ___ running 'baz' at '/bar' |
| 63 (...) |
| 64 |
| 65 will result in 2 items of len((...).splitlines()) each. |
| 66 """ |
| 67 results = [] |
| 68 for line in stdout.splitlines(False): |
| 69 # Intentionally skips empty lines. |
| 70 if not line: |
| 71 continue |
| 72 if line.startswith('__'): |
| 73 match = re.match(r'^________ ([a-z]+) \'(.*)\' in \'(.*)\'$', line) |
| 74 if not match: |
| 75 match = re.match(r'^_____ (.*) is missing, synching instead$', line) |
| 76 if match: |
| 77 # Blah, it's when a dependency is deleted, we should probably not |
| 78 # output this message. |
| 79 results.append([line]) |
| 80 else: |
| 81 print line |
| 82 raise Exception('fail', line) |
| 83 else: |
| 84 results.append([[match.group(1), match.group(2), match.group(3)]]) |
| 85 else: |
| 86 if not results: |
| 87 # TODO(maruel): gclient's git stdout is inconsistent. |
| 88 # This should fail the test instead!! |
| 89 pass |
| 90 else: |
| 91 results[-1].append(line) |
| 92 return results |
| 93 |
| 94 def checkBlock(self, stdout, items): |
| 95 results = self.splitBlock(stdout) |
| 96 for i in xrange(min(len(results), len(items))): |
| 97 if isinstance(items[i], (list, tuple)): |
| 98 verb = items[i][0] |
| 99 path = items[i][1] |
| 100 else: |
| 101 verb = items[i] |
| 102 path = self.root_dir |
| 103 self.checkString(results[i][0][0], verb) |
| 104 self.checkString(results[i][0][2], path) |
| 105 self.assertEquals(len(results), len(items)) |
| 106 return results |
| 107 |
| 108 def svnBlockCleanup(self, out): |
| 109 """Work around svn status difference between svn 1.5 and svn 1.6 |
| 110 I don't know why but on Windows they are reversed. So sorts the items.""" |
| 111 for i in xrange(len(out)): |
| 112 if len(out[i]) < 2: |
| 113 continue |
| 114 out[i] = [out[i][0]] + sorted([x[1:].strip() for x in out[i][1:]]) |
| 115 return out |
| 116 |
| 50 | 117 |
| 51 class GClientSmoke(GClientSmokeBase): | 118 class GClientSmoke(GClientSmokeBase): |
| 52 def testHelp(self): | 119 def testHelp(self): |
| 53 """testHelp: make sure no new command was added.""" | 120 """testHelp: make sure no new command was added.""" |
| 54 result = self.gclient(['help']) | 121 result = self.gclient(['help']) |
| 55 self.assertEquals(1197, len(result[0])) | 122 self.assertEquals(1197, len(result[0])) |
| 56 self.assertEquals(0, len(result[1])) | 123 self.assertEquals(0, len(result[1])) |
| 57 self.assertEquals(0, result[2]) | 124 self.assertEquals(0, result[2]) |
| 58 | 125 |
| 59 def testUnknown(self): | 126 def testUnknown(self): |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 | 191 |
| 125 class GClientSmokeSVN(GClientSmokeBase): | 192 class GClientSmokeSVN(GClientSmokeBase): |
| 126 def setUp(self): | 193 def setUp(self): |
| 127 GClientSmokeBase.setUp(self) | 194 GClientSmokeBase.setUp(self) |
| 128 self.FAKE_REPOS.setUpSVN() | 195 self.FAKE_REPOS.setUpSVN() |
| 129 | 196 |
| 130 def testSync(self): | 197 def testSync(self): |
| 131 # TODO(maruel): safesync. | 198 # TODO(maruel): safesync. |
| 132 self.gclient(['config', self.svn_base + 'trunk/src/']) | 199 self.gclient(['config', self.svn_base + 'trunk/src/']) |
| 133 # Test unversioned checkout. | 200 # Test unversioned checkout. |
| 134 results = self.gclient(['sync', '--deps', 'mac']) | 201 self.parseGclient(['sync', '--deps', 'mac'], |
| 135 logging.debug(results[0]) | 202 ['running', 'running', 'running', 'running']) |
| 136 out = results[0].splitlines(False) | 203 tree = self.mangle_svn_tree( |
| 137 # TODO(maruel): Have real verification here, I wonder why it differs. | 204 ('trunk/src@2', 'src'), |
| 138 self.assertTrue(17 <= len(out), out) | 205 ('trunk/third_party/foo@1', 'src/third_party/foo'), |
| 139 self.assertTrue(20 >= len(out), out) | 206 ('trunk/other@2', 'src/other')) |
| 140 self.checkString('', results[1]) | |
| 141 self.assertEquals(0, results[2]) | |
| 142 tree = mangle_svn_tree( | |
| 143 ('trunk/src', 'src', self.FAKE_REPOS.svn_revs[-1]), | |
| 144 ('trunk/third_party/foo', 'src/third_party/foo', | |
| 145 self.FAKE_REPOS.svn_revs[1]), | |
| 146 ('trunk/other', 'src/other', self.FAKE_REPOS.svn_revs[2]), | |
| 147 ) | |
| 148 tree['src/svn_hooked1'] = 'svn_hooked1' | 207 tree['src/svn_hooked1'] = 'svn_hooked1' |
| 149 self.assertTree(tree) | 208 self.assertTree(tree) |
| 150 | 209 |
| 151 # Manually remove svn_hooked1 before synching to make sure it's not | 210 # Manually remove svn_hooked1 before synching to make sure it's not |
| 152 # recreated. | 211 # recreated. |
| 153 os.remove(join(self.root_dir, 'src', 'svn_hooked1')) | 212 os.remove(join(self.root_dir, 'src', 'svn_hooked1')) |
| 154 | 213 |
| 155 # Test incremental versioned sync: sync backward. | 214 # Test incremental versioned sync: sync backward. |
| 156 results = self.gclient(['sync', '--revision', 'src@1', '--deps', 'mac', | 215 self.parseGclient(['sync', '--revision', 'src@1', '--deps', 'mac', |
| 157 '--delete_unversioned_trees']) | 216 '--delete_unversioned_trees'], |
| 158 logging.debug(results[0]) | 217 ['running', 'running', 'running', 'running', 'deleting']) |
| 159 out = results[0].splitlines(False) | 218 tree = self.mangle_svn_tree( |
| 160 # TODO(maruel): Have real verification here, I wonder why it differs. | 219 ('trunk/src@1', 'src'), |
| 161 self.assertTrue(19 <= len(out), out) | 220 ('trunk/third_party/foo@2', 'src/third_party/fpp'), |
| 162 self.assertTrue(23 >= len(out), out) | 221 ('trunk/other@2', 'src/other'), |
| 163 self.checkString('', results[1]) | 222 ('trunk/third_party/foo@2', 'src/third_party/prout')) |
| 164 self.assertEquals(0, results[2]) | |
| 165 tree = mangle_svn_tree( | |
| 166 ('trunk/src', 'src', self.FAKE_REPOS.svn_revs[1]), | |
| 167 ('trunk/third_party/foo', 'src/third_party/fpp', | |
| 168 self.FAKE_REPOS.svn_revs[2]), | |
| 169 ('trunk/other', 'src/other', self.FAKE_REPOS.svn_revs[2]), | |
| 170 ('trunk/third_party/foo', 'src/third_party/prout', | |
| 171 self.FAKE_REPOS.svn_revs[2]), | |
| 172 ) | |
| 173 self.assertTree(tree) | 223 self.assertTree(tree) |
| 174 # Test incremental sync: delete-unversioned_trees isn't there. | 224 # Test incremental sync: delete-unversioned_trees isn't there. |
| 175 results = self.gclient(['sync', '--deps', 'mac']) | 225 self.parseGclient(['sync', '--deps', 'mac'], |
| 176 logging.debug(results[0]) | 226 ['running', 'running', 'running', 'running']) |
| 177 out = results[0].splitlines(False) | 227 tree = self.mangle_svn_tree( |
| 178 # TODO(maruel): Have real verification here, I wonder why it differs. | 228 ('trunk/src@2', 'src'), |
| 179 self.assertTrue(21 <= len(out), out) | 229 ('trunk/third_party/foo@2', 'src/third_party/fpp'), |
| 180 self.assertTrue(24 >= len(out), out) | 230 ('trunk/third_party/foo@1', 'src/third_party/foo'), |
| 181 self.checkString('', results[1]) | 231 ('trunk/other@2', 'src/other'), |
| 182 self.assertEquals(0, results[2]) | 232 ('trunk/third_party/foo@2', 'src/third_party/prout')) |
| 183 tree = mangle_svn_tree( | |
| 184 ('trunk/src', 'src', self.FAKE_REPOS.svn_revs[2]), | |
| 185 ('trunk/third_party/foo', 'src/third_party/fpp', | |
| 186 self.FAKE_REPOS.svn_revs[2]), | |
| 187 ('trunk/third_party/foo', 'src/third_party/foo', | |
| 188 self.FAKE_REPOS.svn_revs[1]), | |
| 189 ('trunk/other', 'src/other', self.FAKE_REPOS.svn_revs[2]), | |
| 190 ('trunk/third_party/foo', 'src/third_party/prout', | |
| 191 self.FAKE_REPOS.svn_revs[2]), | |
| 192 ) | |
| 193 tree['src/svn_hooked1'] = 'svn_hooked1' | 233 tree['src/svn_hooked1'] = 'svn_hooked1' |
| 194 self.assertTree(tree) | 234 self.assertTree(tree) |
| 195 | 235 |
| 196 def testSyncIgnoredSolutionName(self): | 236 def testSyncIgnoredSolutionName(self): |
| 197 """TODO(maruel): This will become an error soon.""" | 237 """TODO(maruel): This will become an error soon.""" |
| 198 self.gclient(['config', self.svn_base + 'trunk/src/']) | 238 self.gclient(['config', self.svn_base + 'trunk/src/']) |
| 199 results = self.gclient(['sync', '--deps', 'mac', '-r', 'invalid@1']) | 239 results = self.gclient(['sync', '--deps', 'mac', '-r', 'invalid@1']) |
| 200 out = results[0].splitlines(False) | 240 self.checkBlock(results[0], ['running', 'running', 'running', 'running']) |
| 201 # TODO(maruel): Have real verification here, I wonder why it differs. | |
| 202 self.assertTrue(17 <= len(out), out) | |
| 203 self.assertTrue(20 >= len(out), out) | |
| 204 self.checkString('Please fix your script, having invalid --revision flags ' | 241 self.checkString('Please fix your script, having invalid --revision flags ' |
| 205 'will soon considered an error.\n', results[1]) | 242 'will soon considered an error.\n', results[1]) |
| 206 self.assertEquals(0, results[2]) | 243 self.assertEquals(0, results[2]) |
| 207 tree = mangle_svn_tree( | 244 tree = self.mangle_svn_tree( |
| 208 ('trunk/src', 'src', self.FAKE_REPOS.svn_revs[2]), | 245 ('trunk/src@2', 'src'), |
| 209 ('trunk/third_party/foo', 'src/third_party/foo', | 246 ('trunk/third_party/foo@1', 'src/third_party/foo'), |
| 210 self.FAKE_REPOS.svn_revs[1]), | 247 ('trunk/other@2', 'src/other')) |
| 211 ('trunk/other', 'src/other', self.FAKE_REPOS.svn_revs[2]), | |
| 212 ) | |
| 213 tree['src/svn_hooked1'] = 'svn_hooked1' | 248 tree['src/svn_hooked1'] = 'svn_hooked1' |
| 214 self.assertTree(tree) | 249 self.assertTree(tree) |
| 215 | 250 |
| 216 def testSyncNoSolutionName(self): | 251 def testSyncNoSolutionName(self): |
| 217 # When no solution name is provided, gclient uses the first solution listed. | 252 # When no solution name is provided, gclient uses the first solution listed. |
| 218 self.gclient(['config', self.svn_base + 'trunk/src/']) | 253 self.gclient(['config', self.svn_base + 'trunk/src/']) |
| 219 results = self.gclient(['sync', '--deps', 'mac', '-r', '1']) | 254 self.parseGclient(['sync', '--deps', 'mac', '-r', '1'], |
| 220 out = results[0].splitlines(False) | 255 ['running', 'running', 'running', 'running']) |
| 221 # TODO(maruel): Have real verification here, I wonder why it differs. | 256 tree = self.mangle_svn_tree( |
| 222 self.assertTrue(19 <= len(out), out) | 257 ('trunk/src@1', 'src'), |
| 223 self.assertTrue(23 >= len(out), out) | 258 ('trunk/third_party/foo@2', 'src/third_party/fpp'), |
| 224 self.checkString('', results[1]) | 259 ('trunk/other@2', 'src/other'), |
| 225 self.assertEquals(0, results[2]) | 260 ('trunk/third_party/foo@2', 'src/third_party/prout')) |
| 226 tree = mangle_svn_tree( | |
| 227 ('trunk/src', 'src', self.FAKE_REPOS.svn_revs[1]), | |
| 228 ('trunk/third_party/foo', 'src/third_party/fpp', | |
| 229 self.FAKE_REPOS.svn_revs[2]), | |
| 230 ('trunk/other', 'src/other', self.FAKE_REPOS.svn_revs[2]), | |
| 231 ('trunk/third_party/foo', 'src/third_party/prout', | |
| 232 self.FAKE_REPOS.svn_revs[2]), | |
| 233 ) | |
| 234 self.assertTree(tree) | 261 self.assertTree(tree) |
| 235 | 262 |
| 236 def testRevertAndStatus(self): | 263 def testRevertAndStatus(self): |
| 237 self.gclient(['config', self.svn_base + 'trunk/src/']) | 264 self.gclient(['config', self.svn_base + 'trunk/src/']) |
| 238 # Tested in testSync. | 265 # Tested in testSync. |
| 239 self.gclient(['sync', '--deps', 'mac']) | 266 self.gclient(['sync', '--deps', 'mac']) |
| 240 write(join(self.root_dir, 'src', 'other', 'hi'), 'Hey!') | 267 write(join(self.root_dir, 'src', 'other', 'hi'), 'Hey!') |
| 241 | 268 |
| 242 results = self.gclient(['status', '--deps', 'mac']) | 269 out = self.parseGclient(['status', '--deps', 'mac'], |
| 243 out = results[0].splitlines(False) | 270 [['running', join(self.root_dir, 'src')], |
| 244 self.assertEquals(out[0], '') | 271 ['running', join(self.root_dir, 'src', 'other')]]) |
| 245 self.assertTrue(out[1].startswith('________ running \'svn status\' in \'')) | 272 out = self.svnBlockCleanup(out) |
| 246 self.assertTrue(out[2].endswith(' svn_hooked1')) | 273 self.checkString('other', out[0][1]) |
| 247 self.assertTrue(out[3].endswith(' other')) | 274 self.checkString('svn_hooked1', out[0][2]) |
| 248 self.assertTrue(out[4].endswith(' ' + join('third_party', 'foo'))) | 275 self.checkString(join('third_party', 'foo'), out[0][3]) |
| 249 self.assertEquals(out[5], '') | 276 self.checkString('hi', out[1][1]) |
| 250 self.assertTrue(out[6].startswith('________ running \'svn status\' in \'')) | 277 self.assertEquals(4, len(out[0])) |
| 251 self.assertTrue(out[7].endswith(' hi')) | 278 self.assertEquals(2, len(out[1])) |
| 252 self.assertEquals(8, len(out)) | |
| 253 self.assertEquals('', results[1]) | |
| 254 self.assertEquals(0, results[2]) | |
| 255 | 279 |
| 256 # Revert implies --force implies running hooks without looking at pattern | 280 # Revert implies --force implies running hooks without looking at pattern |
| 257 # matching. | 281 # matching. |
| 258 results = self.gclient(['revert', '--deps', 'mac']) | 282 results = self.gclient(['revert', '--deps', 'mac']) |
| 259 out = results[0].splitlines(False) | 283 out = self.splitBlock(results[0]) |
| 260 self.assertEquals(22, len(out)) | 284 self.assertEquals(7, len(out)) |
| 261 self.checkString('', results[1]) | 285 self.checkString('', results[1]) |
| 262 self.assertEquals(0, results[2]) | 286 self.assertEquals(0, results[2]) |
| 263 tree = mangle_svn_tree( | 287 tree = self.mangle_svn_tree( |
| 264 ('trunk/src', 'src', self.FAKE_REPOS.svn_revs[-1]), | 288 ('trunk/src@2', 'src'), |
| 265 ('trunk/third_party/foo', 'src/third_party/foo', | 289 ('trunk/third_party/foo@1', 'src/third_party/foo'), |
| 266 self.FAKE_REPOS.svn_revs[1]), | 290 ('trunk/other@2', 'src/other')) |
| 267 ('trunk/other', 'src/other', self.FAKE_REPOS.svn_revs[2]), | |
| 268 ) | |
| 269 tree['src/svn_hooked1'] = 'svn_hooked1' | 291 tree['src/svn_hooked1'] = 'svn_hooked1' |
| 270 tree['src/svn_hooked2'] = 'svn_hooked2' | 292 tree['src/svn_hooked2'] = 'svn_hooked2' |
| 271 self.assertTree(tree) | 293 self.assertTree(tree) |
| 272 | 294 |
| 273 results = self.gclient(['status', '--deps', 'mac']) | 295 out = self.parseGclient(['status', '--deps', 'mac'], |
| 274 out = results[0].splitlines(False) | 296 [['running', join(self.root_dir, 'src')]]) |
| 275 self.assertEquals(out[0], '') | 297 out = self.svnBlockCleanup(out) |
| 276 self.assertTrue(out[1].startswith('________ running \'svn status\' in \'')) | 298 self.checkString('other', out[0][1]) |
| 277 self.assertTrue(out[2].endswith(' svn_hooked1')) | 299 self.checkString('svn_hooked1', out[0][2]) |
| 278 # I don't know why but on Windows they are reversed. | 300 self.checkString('svn_hooked2', out[0][3]) |
| 279 if (not (out[3].endswith(' other') and | 301 self.checkString(join('third_party', 'foo'), out[0][4]) |
| 280 out[4].endswith(' svn_hooked2')) and | 302 self.assertEquals(5, len(out[0])) |
| 281 not (out[3].endswith(' svn_hooked2') and | |
| 282 out[4].endswith(' other'))): | |
| 283 self.assertEquals(out[3].endswith(' svn_hooked2')) | |
| 284 self.assertEquals(out[4].endswith(' other')) | |
| 285 self.assertTrue(out[5].endswith(' ' + join('third_party', 'foo'))) | |
| 286 self.assertEquals(6, len(out)) | |
| 287 self.checkString('', results[1]) | |
| 288 self.assertEquals(0, results[2]) | |
| 289 | 303 |
| 290 def testRevertAndStatusDepsOs(self): | 304 def testRevertAndStatusDepsOs(self): |
| 291 self.gclient(['config', self.svn_base + 'trunk/src/']) | 305 self.gclient(['config', self.svn_base + 'trunk/src/']) |
| 292 # Tested in testSync. | 306 # Tested in testSync. |
| 293 self.gclient(['sync', '--deps', 'mac', '--revision', 'src@1']) | 307 self.gclient(['sync', '--deps', 'mac', '--revision', 'src@1']) |
| 294 write(join(self.root_dir, 'src', 'other', 'hi'), 'Hey!') | 308 write(join(self.root_dir, 'src', 'other', 'hi'), 'Hey!') |
| 295 | 309 |
| 296 results = self.gclient(['status', '--deps', 'mac']) | 310 # Without --verbose, gclient won't output the directories without |
| 297 out = results[0].splitlines(False) | 311 # modification. |
| 298 self.assertEquals(out[0], '') | 312 out = self.parseGclient(['status', '--deps', 'mac'], |
| 299 self.assertTrue(out[1].startswith('________ running \'svn status\' in \'')) | 313 [['running', join(self.root_dir, 'src')], |
| 300 self.assertTrue(out[2].endswith(' other')) | 314 ['running', join(self.root_dir, 'src', 'other')]]) |
| 301 self.assertTrue(out[3].endswith(' ' + join('third_party', 'fpp'))) | 315 out = self.svnBlockCleanup(out) |
| 302 self.assertTrue(out[4].endswith(' ' + join('third_party', 'prout'))) | 316 self.checkString('other', out[0][1]) |
| 303 self.assertEquals(out[5], '') | 317 self.checkString(join('third_party', 'fpp'), out[0][2]) |
| 304 self.assertTrue(out[6].startswith('________ running \'svn status\' in \'')) | 318 self.checkString(join('third_party', 'prout'), out[0][3]) |
| 305 self.assertTrue(out[7].endswith(' hi')) | 319 self.checkString('hi', out[1][1]) |
| 306 self.assertEquals(8, len(out)) | 320 self.assertEquals(4, len(out[0])) |
| 307 self.assertEquals('', results[1]) | 321 self.assertEquals(2, len(out[1])) |
| 308 self.assertEquals(0, results[2]) | 322 |
| 323 # So verify it works with --verbose. |
| 324 out = self.parseGclient(['status', '--deps', 'mac', '--verbose'], |
| 325 [['running', join(self.root_dir, 'src')], |
| 326 ['running', join(self.root_dir, 'src', 'other')], |
| 327 ['running', join(self.root_dir, 'src', 'third_party', 'fpp')], |
| 328 ['running', join(self.root_dir, 'src', 'third_party', 'prout')]]) |
| 329 out = self.svnBlockCleanup(out) |
| 330 self.checkString('other', out[0][1]) |
| 331 self.checkString(join('third_party', 'fpp'), out[0][2]) |
| 332 self.checkString(join('third_party', 'prout'), out[0][3]) |
| 333 self.checkString('hi', out[1][1]) |
| 334 self.assertEquals(4, len(out[0])) |
| 335 self.assertEquals(2, len(out[1])) |
| 309 | 336 |
| 310 # Revert implies --force implies running hooks without looking at pattern | 337 # Revert implies --force implies running hooks without looking at pattern |
| 311 # matching. | 338 # matching. |
| 339 # TODO(maruel): In general, gclient revert output is wrong. It should output |
| 340 # the file list after some ___ running 'svn status' |
| 312 results = self.gclient(['revert', '--deps', 'mac']) | 341 results = self.gclient(['revert', '--deps', 'mac']) |
| 313 out = results[0].splitlines(False) | 342 out = self.splitBlock(results[0]) |
| 314 self.assertEquals(24, len(out)) | 343 self.assertEquals(7, len(out)) |
| 315 self.checkString('', results[1]) | 344 self.checkString('', results[1]) |
| 316 self.assertEquals(0, results[2]) | 345 self.assertEquals(0, results[2]) |
| 317 tree = mangle_svn_tree( | 346 tree = self.mangle_svn_tree( |
| 318 ('trunk/src', 'src', self.FAKE_REPOS.svn_revs[1]), | 347 ('trunk/src@1', 'src'), |
| 319 ('trunk/third_party/foo', 'src/third_party/fpp', | 348 ('trunk/third_party/foo@2', 'src/third_party/fpp'), |
| 320 self.FAKE_REPOS.svn_revs[2]), | 349 ('trunk/other@2', 'src/other'), |
| 321 ('trunk/other', 'src/other', self.FAKE_REPOS.svn_revs[2]), | 350 ('trunk/third_party/prout@2', 'src/third_party/prout')) |
| 322 ('trunk/third_party/prout', 'src/third_party/prout', | |
| 323 self.FAKE_REPOS.svn_revs[2]), | |
| 324 ) | |
| 325 self.assertTree(tree) | 351 self.assertTree(tree) |
| 326 | 352 |
| 327 results = self.gclient(['status', '--deps', 'mac']) | 353 out = self.parseGclient(['status', '--deps', 'mac'], |
| 328 out = results[0].splitlines(False) | 354 [['running', join(self.root_dir, 'src')]]) |
| 329 self.assertEquals(out[0], '') | 355 out = self.svnBlockCleanup(out) |
| 330 self.assertTrue(out[1].startswith('________ running \'svn status\' in \'')) | 356 self.checkString('other', out[0][1]) |
| 331 self.assertTrue(out[2].endswith(' other')) | 357 self.checkString(join('third_party', 'fpp'), out[0][2]) |
| 332 self.assertTrue(out[3].endswith(' ' + join('third_party', 'fpp'))) | 358 self.checkString(join('third_party', 'prout'), out[0][3]) |
| 333 self.assertTrue(out[4].endswith(' ' + join('third_party', 'prout'))) | 359 self.assertEquals(4, len(out[0])) |
| 334 self.assertEquals(5, len(out)) | |
| 335 self.checkString('', results[1]) | |
| 336 self.assertEquals(0, results[2]) | |
| 337 | 360 |
| 338 def testRunHooks(self): | 361 def testRunHooks(self): |
| 339 self.gclient(['config', self.svn_base + 'trunk/src/']) | 362 self.gclient(['config', self.svn_base + 'trunk/src/']) |
| 340 self.gclient(['sync', '--deps', 'mac']) | 363 self.gclient(['sync', '--deps', 'mac']) |
| 341 results = self.gclient(['runhooks', '--deps', 'mac']) | 364 out = self.parseGclient(['runhooks', '--deps', 'mac'], |
| 342 out = results[0].splitlines(False) | 365 ['running', 'running']) |
| 343 self.assertEquals(4, len(out)) | 366 self.checkString(1, len(out[0])) |
| 344 self.assertEquals(out[0], '') | 367 self.checkString(1, len(out[1])) |
| 345 self.assertTrue(re.match(r'^________ running \'.*?python(.exe)? -c ' | |
| 346 r'open\(\'src/svn_hooked1\', \'w\'\)\.write\(\'svn_hooked1\'\)\' in \'.*', | |
| 347 out[1])) | |
| 348 self.assertEquals(out[2], '') | |
| 349 # runhooks runs all hooks even if not matching by design. | |
| 350 self.assertTrue(re.match(r'^________ running \'.*?python(.exe)? -c ' | |
| 351 r'open\(\'src/svn_hooked2\', \'w\'\)\.write\(\'svn_hooked2\'\)\' in \'.*', | |
| 352 out[3])) | |
| 353 self.checkString('', results[1]) | |
| 354 self.assertEquals(0, results[2]) | |
| 355 | 368 |
| 356 def testRunHooksDepsOs(self): | 369 def testRunHooksDepsOs(self): |
| 357 self.gclient(['config', self.svn_base + 'trunk/src/']) | 370 self.gclient(['config', self.svn_base + 'trunk/src/']) |
| 358 self.gclient(['sync', '--deps', 'mac', '--revision', 'src@1']) | 371 self.gclient(['sync', '--deps', 'mac', '--revision', 'src@1']) |
| 359 results = self.gclient(['runhooks', '--deps', 'mac']) | 372 out = self.parseGclient(['runhooks', '--deps', 'mac'], []) |
| 360 self.check(('', '', 0), results) | 373 self.assertEquals([], out) |
| 361 | 374 |
| 362 def testRevInfo(self): | 375 def testRevInfo(self): |
| 363 # TODO(maruel): Test multiple solutions. | 376 # TODO(maruel): Test multiple solutions. |
| 364 self.gclient(['config', self.svn_base + 'trunk/src/']) | 377 self.gclient(['config', self.svn_base + 'trunk/src/']) |
| 365 self.gclient(['sync', '--deps', 'mac']) | 378 self.gclient(['sync', '--deps', 'mac']) |
| 366 results = self.gclient(['revinfo', '--deps', 'mac']) | 379 results = self.gclient(['revinfo', '--deps', 'mac']) |
| 367 out = ('src: %(base)s/src@2;\n' | 380 out = ('src: %(base)s/src@2;\n' |
| 368 'src/other: %(base)s/other@2;\n' | 381 'src/other: %(base)s/other@2;\n' |
| 369 'src/third_party/foo: %(base)s/third_party/foo@1\n' % | 382 'src/third_party/foo: %(base)s/third_party/foo@1\n' % |
| 370 { 'base': self.svn_base + 'trunk' }) | 383 { 'base': self.svn_base + 'trunk' }) |
| 371 self.check((out, '', 0), results) | 384 self.check((out, '', 0), results) |
| 372 | 385 |
| 373 | 386 |
| 374 class GClientSmokeGIT(GClientSmokeBase): | 387 class GClientSmokeGIT(GClientSmokeBase): |
| 375 def setUp(self): | 388 def setUp(self): |
| 376 GClientSmokeBase.setUp(self) | 389 GClientSmokeBase.setUp(self) |
| 377 self.enabled = self.FAKE_REPOS.setUpGIT() | 390 self.enabled = self.FAKE_REPOS.setUpGIT() |
| 378 | 391 |
| 379 def testSync(self): | 392 def testSync(self): |
| 380 if not self.enabled: | 393 if not self.enabled: |
| 381 return | 394 return |
| 382 # TODO(maruel): safesync. | 395 # TODO(maruel): safesync. |
| 383 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) | 396 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) |
| 384 # Test unversioned checkout. | 397 # Test unversioned checkout. |
| 385 results = self.gclient(['sync', '--deps', 'mac']) | 398 results = self.gclient(['sync', '--deps', 'mac']) |
| 386 out = results[0].splitlines(False) | 399 self.checkBlock(results[0], ['running', 'running']) |
| 387 # TODO(maruel): http://crosbug.com/3582 hooks run even if not matching, must | 400 # TODO(maruel): http://crosbug.com/3582 hooks run even if not matching, must |
| 388 # add sync parsing to get the list of updated files. | 401 # add sync parsing to get the list of updated files. |
| 389 self.assertEquals(13, len(out)) | 402 #self.assertTrue(results[1].startswith('Switched to a new branch \'')) |
| 390 self.assertTrue(results[1].startswith('Switched to a new branch \'')) | |
| 391 self.assertEquals(0, results[2]) | 403 self.assertEquals(0, results[2]) |
| 392 tree = mangle_git_tree( | 404 tree = self.mangle_git_tree(('repo_1@2', 'src'), |
| 393 ('src', self.FAKE_REPOS.git_hashes['repo_1'][1][1]), | 405 ('repo_2@1', 'src/repo2'), |
| 394 ('src/repo2', self.FAKE_REPOS.git_hashes['repo_2'][0][1]), | 406 ('repo_3@2', 'src/repo2/repo_renamed')) |
| 395 ('src/repo2/repo_renamed', self.FAKE_REPOS.git_hashes['repo_3'][1][1]), | |
| 396 ) | |
| 397 tree['src/git_hooked1'] = 'git_hooked1' | 407 tree['src/git_hooked1'] = 'git_hooked1' |
| 398 tree['src/git_hooked2'] = 'git_hooked2' | 408 tree['src/git_hooked2'] = 'git_hooked2' |
| 399 self.assertTree(tree) | 409 self.assertTree(tree) |
| 400 | 410 |
| 401 # Manually remove git_hooked1 before synching to make sure it's not | 411 # Manually remove git_hooked1 before synching to make sure it's not |
| 402 # recreated. | 412 # recreated. |
| 403 os.remove(join(self.root_dir, 'src', 'git_hooked1')) | 413 os.remove(join(self.root_dir, 'src', 'git_hooked1')) |
| 404 | 414 |
| 405 # Test incremental versioned sync: sync backward. | 415 # Test incremental versioned sync: sync backward. |
| 406 results = self.gclient(['sync', '--revision', | 416 results = self.gclient(['sync', '--revision', |
| 407 'src@' + self.FAKE_REPOS.git_hashes['repo_1'][0][0], | 417 'src@' + self.githash('repo_1', 1), |
| 408 '--deps', 'mac', '--delete_unversioned_trees']) | 418 '--deps', 'mac', '--delete_unversioned_trees']) |
| 409 logging.debug(results[0]) | 419 # gclient's git output is unparsable and all messed up. Don't look at it, it |
| 410 out = results[0].splitlines(False) | 420 # hurts the smoke test's eyes. Add "print out" here if you want to dare to |
| 411 # TODO(maruel): Have real verification here, I wonder why it differs. | 421 # parse it. So just assert it's not empty and look at the result on the file |
| 412 self.assertTrue(20 <= len(out), out) | 422 # system instead. |
| 413 self.assertTrue(23 >= len(out), out) | 423 self.assertEquals('', results[1]) |
| 414 self.checkString('', results[1]) | |
| 415 self.assertEquals(0, results[2]) | 424 self.assertEquals(0, results[2]) |
| 416 tree = mangle_git_tree( | 425 tree = self.mangle_git_tree(('repo_1@1', 'src'), |
| 417 ('src', self.FAKE_REPOS.git_hashes['repo_1'][0][1]), | 426 ('repo_2@2', 'src/repo2'), |
| 418 ('src/repo2', self.FAKE_REPOS.git_hashes['repo_2'][1][1]), | 427 ('repo_3@2', 'src/repo2/repo3'), |
| 419 ('src/repo2/repo3', self.FAKE_REPOS.git_hashes['repo_3'][1][1]), | 428 ('repo_4@2', 'src/repo4')) |
| 420 ('src/repo4', self.FAKE_REPOS.git_hashes['repo_4'][1][1]), | |
| 421 ) | |
| 422 tree['src/git_hooked2'] = 'git_hooked2' | 429 tree['src/git_hooked2'] = 'git_hooked2' |
| 423 self.assertTree(tree) | 430 self.assertTree(tree) |
| 424 # Test incremental sync: delete-unversioned_trees isn't there. | 431 # Test incremental sync: delete-unversioned_trees isn't there. |
| 425 results = self.gclient(['sync', '--deps', 'mac']) | 432 results = self.gclient(['sync', '--deps', 'mac']) |
| 426 logging.debug(results[0]) | 433 # See comment above about parsing gclient's git output. |
| 427 out = results[0].splitlines(False) | 434 self.assertEquals('', results[1]) |
| 428 self.assertEquals(25, len(out)) | |
| 429 self.checkString('', results[1]) | |
| 430 self.assertEquals(0, results[2]) | 435 self.assertEquals(0, results[2]) |
| 431 tree = mangle_git_tree( | 436 tree = self.mangle_git_tree(('repo_1@2', 'src'), |
| 432 ('src', self.FAKE_REPOS.git_hashes['repo_1'][1][1]), | 437 ('repo_2@1', 'src/repo2'), |
| 433 ('src/repo2', self.FAKE_REPOS.git_hashes['repo_2'][1][1]), | 438 ('repo_3@2', 'src/repo2/repo3'), |
| 434 ('src/repo2/repo3', self.FAKE_REPOS.git_hashes['repo_3'][1][1]), | 439 ('repo_3@2', 'src/repo2/repo_renamed'), |
| 435 ('src/repo2/repo_renamed', self.FAKE_REPOS.git_hashes['repo_3'][1][1]), | 440 ('repo_4@2', 'src/repo4')) |
| 436 ('src/repo4', self.FAKE_REPOS.git_hashes['repo_4'][1][1]), | |
| 437 ) | |
| 438 tree['src/git_hooked1'] = 'git_hooked1' | 441 tree['src/git_hooked1'] = 'git_hooked1' |
| 439 tree['src/git_hooked2'] = 'git_hooked2' | 442 tree['src/git_hooked2'] = 'git_hooked2' |
| 440 self.assertTree(tree) | 443 self.assertTree(tree) |
| 441 | 444 |
| 442 def testSyncIgnoredSolutionName(self): | 445 def testSyncIgnoredSolutionName(self): |
| 443 """TODO(maruel): This will become an error soon.""" | 446 """TODO(maruel): This will become an error soon.""" |
| 444 if not self.enabled: | 447 if not self.enabled: |
| 445 return | 448 return |
| 446 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) | 449 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) |
| 447 results = self.gclient([ | 450 results = self.gclient(['sync', '--deps', 'mac', '--revision', |
| 448 'sync', '--deps', 'mac', '--revision', | 451 'invalid@' + self.githash('repo_1', 1)]) |
| 449 'invalid@' + self.FAKE_REPOS.git_hashes['repo_1'][0][0], | 452 self.checkBlock(results[0], ['running', 'running']) |
| 450 ]) | |
| 451 out = results[0].splitlines(False) | |
| 452 | |
| 453 self.assertEquals(13, len(out)) | |
| 454 # TODO(maruel): git shouldn't output to stderr... | 453 # TODO(maruel): git shouldn't output to stderr... |
| 455 self.checkString('Please fix your script, having invalid --revision flags ' | 454 self.checkString('Please fix your script, having invalid --revision flags ' |
| 456 'will soon considered an error.\nSwitched to a new branch \'%s\'\n' % | 455 'will soon considered an error.\n', |
| 457 self.FAKE_REPOS.git_hashes['repo_2'][0][0][:7], | |
| 458 results[1]) | 456 results[1]) |
| 457 #self.checkString('Please fix your script, having invalid --revision flags ' |
| 458 # 'will soon considered an error.\nSwitched to a new branch \'%s\'\n' % |
| 459 # self.githash('repo_2', 1)[:7], |
| 460 # results[1]) |
| 459 self.assertEquals(0, results[2]) | 461 self.assertEquals(0, results[2]) |
| 460 tree = mangle_git_tree( | 462 tree = self.mangle_git_tree(('repo_1@2', 'src'), |
| 461 ('src', self.FAKE_REPOS.git_hashes['repo_1'][1][1]), | 463 ('repo_2@1', 'src/repo2'), |
| 462 ('src/repo2', self.FAKE_REPOS.git_hashes['repo_2'][0][1]), | 464 ('repo_3@2', 'src/repo2/repo_renamed')) |
| 463 ('src/repo2/repo_renamed', | |
| 464 self.FAKE_REPOS.git_hashes['repo_3'][1][1]), | |
| 465 ) | |
| 466 tree['src/git_hooked1'] = 'git_hooked1' | 465 tree['src/git_hooked1'] = 'git_hooked1' |
| 467 tree['src/git_hooked2'] = 'git_hooked2' | 466 tree['src/git_hooked2'] = 'git_hooked2' |
| 468 self.assertTree(tree) | 467 self.assertTree(tree) |
| 469 | 468 |
| 470 def testSyncNoSolutionName(self): | 469 def testSyncNoSolutionName(self): |
| 471 if not self.enabled: | 470 if not self.enabled: |
| 472 return | 471 return |
| 473 # When no solution name is provided, gclient uses the first solution listed. | 472 # When no solution name is provided, gclient uses the first solution listed. |
| 474 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) | 473 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) |
| 475 results = self.gclient([ | 474 results = self.gclient(['sync', '--deps', 'mac', |
| 476 'sync', '--deps', 'mac', '--revision', | 475 '--revision', self.githash('repo_1', 1)]) |
| 477 self.FAKE_REPOS.git_hashes['repo_1'][0][0], | 476 self.checkBlock(results[0], []) |
| 478 ]) | |
| 479 out = results[0].splitlines(False) | |
| 480 # TODO(maruel): Have real verification here, I wonder why it differs. | |
| 481 self.assertTrue(12 <= len(out), out) | |
| 482 self.assertTrue(15 >= len(out), out) | |
| 483 # TODO(maruel): git shouldn't output to stderr... | 477 # TODO(maruel): git shouldn't output to stderr... |
| 484 self.checkString('Switched to a new branch \'%s\'\n' | 478 #self.checkString('Switched to a new branch \'%s\'\n' |
| 485 % self.FAKE_REPOS.git_hashes['repo_1'][0][0], results[1]) | 479 # % self.githash('repo_1', 1), results[1]) |
| 480 self.checkString('', results[1]) |
| 486 self.assertEquals(0, results[2]) | 481 self.assertEquals(0, results[2]) |
| 487 tree = mangle_git_tree( | 482 tree = self.mangle_git_tree(('repo_1@1', 'src'), |
| 488 ('src', self.FAKE_REPOS.git_hashes['repo_1'][0][1]), | 483 ('repo_2@2', 'src/repo2'), |
| 489 ('src/repo2', self.FAKE_REPOS.git_hashes['repo_2'][1][1]), | 484 ('repo_3@2', 'src/repo2/repo3'), |
| 490 ('src/repo2/repo3', self.FAKE_REPOS.git_hashes['repo_3'][1][1]), | 485 ('repo_4@2', 'src/repo4')) |
| 491 ('src/repo4', self.FAKE_REPOS.git_hashes['repo_4'][1][1]), | |
| 492 ) | |
| 493 self.assertTree(tree) | 486 self.assertTree(tree) |
| 494 | 487 |
| 495 def testRevertAndStatus(self): | 488 def testRevertAndStatus(self): |
| 496 """TODO(maruel): Remove this line once this test is fixed.""" | 489 """TODO(maruel): Remove this line once this test is fixed.""" |
| 497 if not self.enabled: | 490 if not self.enabled: |
| 498 return | 491 return |
| 499 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) | 492 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) |
| 500 # Tested in testSync. | 493 # Tested in testSync. |
| 501 self.gclient(['sync', '--deps', 'mac']) | 494 self.gclient(['sync', '--deps', 'mac']) |
| 502 write(join(self.root_dir, 'src', 'repo2', 'hi'), 'Hey!') | 495 write(join(self.root_dir, 'src', 'repo2', 'hi'), 'Hey!') |
| 503 | 496 |
| 504 results = self.gclient(['status', '--deps', 'mac']) | 497 results = self.gclient(['status', '--deps', 'mac']) |
| 505 out = results[0].splitlines(False) | 498 out = results[0].splitlines(False) |
| 506 # TODO(maruel): http://crosbug.com/3584 It should output the unversioned | 499 # TODO(maruel): http://crosbug.com/3584 It should output the unversioned |
| 507 # files. | 500 # files. |
| 508 self.assertEquals(0, len(out)) | 501 self.assertEquals(0, len(out)) |
| 509 | 502 |
| 510 # Revert implies --force implies running hooks without looking at pattern | 503 # Revert implies --force implies running hooks without looking at pattern |
| 511 # matching. | 504 # matching. |
| 512 results = self.gclient(['revert', '--deps', 'mac']) | 505 results = self.gclient(['revert', '--deps', 'mac']) |
| 513 out = results[0].splitlines(False) | 506 out = results[0].splitlines(False) |
| 514 # TODO(maruel): http://crosbug.com/3583 It just runs the hooks right now. | 507 # TODO(maruel): http://crosbug.com/3583 It just runs the hooks right now. |
| 515 self.assertEquals(7, len(out)) | 508 self.assertEquals(7, len(out)) |
| 516 self.checkString('', results[1]) | 509 self.checkString('', results[1]) |
| 517 self.assertEquals(0, results[2]) | 510 self.assertEquals(0, results[2]) |
| 518 tree = mangle_git_tree( | 511 tree = self.mangle_git_tree(('repo_1@2', 'src'), |
| 519 ('src', self.FAKE_REPOS.git_hashes['repo_1'][1][1]), | 512 ('repo_2@1', 'src/repo2'), |
| 520 ('src/repo2', self.FAKE_REPOS.git_hashes['repo_2'][0][1]), | 513 ('repo_3@2', 'src/repo2/repo_renamed')) |
| 521 ('src/repo2/repo_renamed', self.FAKE_REPOS.git_hashes['repo_3'][1][1]), | |
| 522 ) | |
| 523 # TODO(maruel): http://crosbug.com/3583 This file should have been removed. | 514 # TODO(maruel): http://crosbug.com/3583 This file should have been removed. |
| 524 tree[join('src', 'repo2', 'hi')] = 'Hey!' | 515 tree[join('src', 'repo2', 'hi')] = 'Hey!' |
| 525 tree['src/git_hooked1'] = 'git_hooked1' | 516 tree['src/git_hooked1'] = 'git_hooked1' |
| 526 tree['src/git_hooked2'] = 'git_hooked2' | 517 tree['src/git_hooked2'] = 'git_hooked2' |
| 527 self.assertTree(tree) | 518 self.assertTree(tree) |
| 528 | 519 |
| 529 results = self.gclient(['status', '--deps', 'mac']) | 520 results = self.gclient(['status', '--deps', 'mac']) |
| 530 out = results[0].splitlines(False) | 521 out = results[0].splitlines(False) |
| 531 # TODO(maruel): http://crosbug.com/3584 It should output the unversioned | 522 # TODO(maruel): http://crosbug.com/3584 It should output the unversioned |
| 532 # files. | 523 # files. |
| 533 self.assertEquals(0, len(out)) | 524 self.assertEquals(0, len(out)) |
| 534 | 525 |
| 535 def testRunHooks(self): | 526 def testRunHooks(self): |
| 536 if not self.enabled: | 527 if not self.enabled: |
| 537 return | 528 return |
| 538 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) | 529 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) |
| 539 self.gclient(['sync', '--deps', 'mac']) | 530 self.gclient(['sync', '--deps', 'mac']) |
| 540 results = self.gclient(['runhooks', '--deps', 'mac']) | 531 tree = self.mangle_git_tree(('repo_1@2', 'src'), |
| 541 logging.debug(results[0]) | 532 ('repo_2@1', 'src/repo2'), |
| 542 out = results[0].splitlines(False) | 533 ('repo_3@2', 'src/repo2/repo_renamed')) |
| 543 self.assertEquals(4, len(out)) | 534 tree['src/git_hooked1'] = 'git_hooked1' |
| 544 self.assertEquals(out[0], '') | 535 tree['src/git_hooked2'] = 'git_hooked2' |
| 545 self.assertTrue(re.match(r'^________ running \'.*?python -c ' | 536 self.assertTree(tree) |
| 546 r'open\(\'src/git_hooked1\', \'w\'\)\.write\(\'git_hooked1\'\)\' in \'.*', | 537 |
| 547 out[1])) | 538 os.remove(join(self.root_dir, 'src', 'git_hooked1')) |
| 548 self.assertEquals(out[2], '') | 539 os.remove(join(self.root_dir, 'src', 'git_hooked2')) |
| 549 # runhooks runs all hooks even if not matching by design. | 540 # runhooks runs all hooks even if not matching by design. |
| 550 self.assertTrue(re.match(r'^________ running \'.*?python -c ' | 541 out = self.parseGclient(['runhooks', '--deps', 'mac'], |
| 551 r'open\(\'src/git_hooked2\', \'w\'\)\.write\(\'git_hooked2\'\)\' in \'.*', | 542 ['running', 'running']) |
| 552 out[3])) | 543 self.assertEquals(1, len(out[0])) |
| 553 self.checkString('', results[1]) | 544 self.assertEquals(1, len(out[1])) |
| 554 self.assertEquals(0, results[2]) | 545 tree = self.mangle_git_tree(('repo_1@2', 'src'), |
| 546 ('repo_2@1', 'src/repo2'), |
| 547 ('repo_3@2', 'src/repo2/repo_renamed')) |
| 548 tree['src/git_hooked1'] = 'git_hooked1' |
| 549 tree['src/git_hooked2'] = 'git_hooked2' |
| 550 self.assertTree(tree) |
| 555 | 551 |
| 556 def testRevInfo(self): | 552 def testRevInfo(self): |
| 557 if not self.enabled: | 553 if not self.enabled: |
| 558 return | 554 return |
| 559 # TODO(maruel): Test multiple solutions. | 555 # TODO(maruel): Test multiple solutions. |
| 560 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) | 556 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) |
| 561 self.gclient(['sync', '--deps', 'mac']) | 557 self.gclient(['sync', '--deps', 'mac']) |
| 562 results = self.gclient(['revinfo', '--deps', 'mac']) | 558 results = self.gclient(['revinfo', '--deps', 'mac']) |
| 563 out = ('src: %(base)srepo_1@%(hash1)s;\n' | 559 out = ('src: %(base)srepo_1@%(hash1)s;\n' |
| 564 'src/repo2: %(base)srepo_2@%(hash2)s;\n' | 560 'src/repo2: %(base)srepo_2@%(hash2)s;\n' |
| 565 'src/repo2/repo_renamed: %(base)srepo_3@%(hash3)s\n' % | 561 'src/repo2/repo_renamed: %(base)srepo_3@%(hash3)s\n' % |
| 566 { | 562 { |
| 567 'base': self.git_base, | 563 'base': self.git_base, |
| 568 'hash1': self.FAKE_REPOS.git_hashes['repo_1'][1][0], | 564 'hash1': self.githash('repo_1', 2), |
| 569 'hash2': self.FAKE_REPOS.git_hashes['repo_2'][0][0], | 565 'hash2': self.githash('repo_2', 1), |
| 570 'hash3': self.FAKE_REPOS.git_hashes['repo_3'][1][0], | 566 'hash3': self.githash('repo_3', 2), |
| 571 }) | 567 }) |
| 572 self.check((out, '', 0), results) | 568 self.check((out, '', 0), results) |
| 573 | 569 |
| 574 | 570 |
| 575 class GClientSmokeBoth(GClientSmokeBase): | 571 class GClientSmokeBoth(GClientSmokeBase): |
| 576 def setUp(self): | 572 def setUp(self): |
| 577 GClientSmokeBase.setUp(self) | 573 GClientSmokeBase.setUp(self) |
| 578 self.FAKE_REPOS.setUpSVN() | 574 self.FAKE_REPOS.setUpSVN() |
| 579 self.enabled = self.FAKE_REPOS.setUpGIT() | 575 self.enabled = self.FAKE_REPOS.setUpGIT() |
| 580 | 576 |
| 581 def testMultiSolutions(self): | 577 def testMultiSolutions(self): |
| 582 if not self.enabled: | 578 if not self.enabled: |
| 583 return | 579 return |
| 584 self.gclient(['config', '--spec', | 580 self.gclient(['config', '--spec', |
| 585 'solutions=[' | 581 'solutions=[' |
| 586 '{"name": "src",' | 582 '{"name": "src",' |
| 587 ' "url": "' + self.svn_base + 'trunk/src/"},' | 583 ' "url": "' + self.svn_base + 'trunk/src/"},' |
| 588 '{"name": "src-git",' | 584 '{"name": "src-git",' |
| 589 '"url": "' + self.git_base + 'repo_1"}]']) | 585 '"url": "' + self.git_base + 'repo_1"}]']) |
| 590 results = self.gclient(['sync', '--deps', 'mac']) | 586 results = self.gclient(['sync', '--deps', 'mac']) |
| 591 out = results[0].splitlines(False) | 587 self.checkBlock(results[0], |
| 592 # TODO(maruel): Have real verification here, I wonder why it differs. | 588 ['running', 'running', 'running', 'running', 'running', |
| 593 self.assertTrue(32 <= len(out), out) | 589 'running', 'running']) |
| 594 self.assertTrue(37 >= len(out), out) | |
| 595 # TODO(maruel): Something's wrong here. git outputs to stderr 'Switched to | 590 # TODO(maruel): Something's wrong here. git outputs to stderr 'Switched to |
| 596 # new branch \'hash\''. | 591 # new branch \'hash\''. |
| 597 #self.checkString('', results[1]) | 592 #self.checkString('', results[1]) |
| 598 self.assertEquals(0, results[2]) | 593 self.assertEquals(0, results[2]) |
| 599 tree = mangle_git_tree( | 594 tree = self.mangle_git_tree(('repo_1@2', 'src-git'), |
| 600 ('src-git', self.FAKE_REPOS.git_hashes['repo_1'][1][1]), | 595 ('repo_2@1', 'src/repo2'), |
| 601 ('src/repo2', self.FAKE_REPOS.git_hashes['repo_2'][0][1]), | 596 ('repo_3@2', 'src/repo2/repo_renamed')) |
| 602 ('src/repo2/repo_renamed', self.FAKE_REPOS.git_hashes['repo_3'][1][1]), | 597 tree.update(self.mangle_svn_tree( |
| 603 ) | 598 ('trunk/src@2', 'src'), |
| 604 tree.update(mangle_svn_tree( | 599 ('trunk/third_party/foo@1', 'src/third_party/foo'), |
| 605 ('trunk/src', 'src', self.FAKE_REPOS.svn_revs[2]), | 600 ('trunk/other@2', 'src/other'))) |
| 606 ('trunk/third_party/foo', 'src/third_party/foo', | |
| 607 self.FAKE_REPOS.svn_revs[1]), | |
| 608 ('trunk/other', 'src/other', self.FAKE_REPOS.svn_revs[2]), | |
| 609 )) | |
| 610 tree['src/git_hooked1'] = 'git_hooked1' | 601 tree['src/git_hooked1'] = 'git_hooked1' |
| 611 tree['src/git_hooked2'] = 'git_hooked2' | 602 tree['src/git_hooked2'] = 'git_hooked2' |
| 612 tree['src/svn_hooked1'] = 'svn_hooked1' | 603 tree['src/svn_hooked1'] = 'svn_hooked1' |
| 613 tree['src/svn_hooked2'] = 'svn_hooked2' | 604 tree['src/svn_hooked2'] = 'svn_hooked2' |
| 614 self.assertTree(tree) | 605 self.assertTree(tree) |
| 615 | 606 |
| 616 def testMultiSolutionsMultiRev(self): | 607 def testMultiSolutionsMultiRev(self): |
| 617 if not self.enabled: | 608 if not self.enabled: |
| 618 return | 609 return |
| 619 self.gclient(['config', '--spec', | 610 self.gclient(['config', '--spec', |
| 620 'solutions=[' | 611 'solutions=[' |
| 621 '{"name": "src",' | 612 '{"name": "src",' |
| 622 ' "url": "' + self.svn_base + 'trunk/src/"},' | 613 ' "url": "' + self.svn_base + 'trunk/src/"},' |
| 623 '{"name": "src-git",' | 614 '{"name": "src-git",' |
| 624 '"url": "' + self.git_base + 'repo_1"}]']) | 615 '"url": "' + self.git_base + 'repo_1"}]']) |
| 625 results = self.gclient([ | 616 results = self.gclient(['sync', '--deps', 'mac', '--revision', '1', |
| 626 'sync', '--deps', 'mac', '--revision', '1', '-r', | 617 '-r', 'src-git@' + self.githash('repo_1', 1)]) |
| 627 'src-git@' + self.FAKE_REPOS.git_hashes['repo_1'][0][0]]) | 618 self.checkBlock(results[0], ['running', 'running', 'running', 'running']) |
| 628 out = results[0].splitlines(False) | |
| 629 # TODO(maruel): Have real verification here, I wonder why it differs. | |
| 630 self.assertTrue(35 <= len(out), out) | |
| 631 self.assertTrue(38 >= len(out), out) | |
| 632 # TODO(maruel): Something's wrong here. git outputs to stderr 'Switched to | 619 # TODO(maruel): Something's wrong here. git outputs to stderr 'Switched to |
| 633 # new branch \'hash\''. | 620 # new branch \'hash\''. |
| 634 #self.checkString('', results[1]) | 621 #self.checkString('', results[1]) |
| 635 self.assertEquals(0, results[2]) | 622 self.assertEquals(0, results[2]) |
| 636 tree = mangle_git_tree( | 623 tree = self.mangle_git_tree(('repo_1@1', 'src-git'), |
| 637 ('src-git', self.FAKE_REPOS.git_hashes['repo_1'][0][1]), | 624 ('repo_2@2', 'src/repo2'), |
| 638 ('src/repo2', self.FAKE_REPOS.git_hashes['repo_2'][1][1]), | 625 ('repo_3@2', 'src/repo2/repo3'), |
| 639 ('src/repo2/repo3', self.FAKE_REPOS.git_hashes['repo_3'][1][1]), | 626 ('repo_4@2', 'src/repo4')) |
| 640 ('src/repo4', self.FAKE_REPOS.git_hashes['repo_4'][1][1]), | 627 tree.update(self.mangle_svn_tree( |
| 641 ) | 628 ('trunk/src@1', 'src'), |
| 642 tree.update(mangle_svn_tree( | 629 ('trunk/third_party/foo@2', 'src/third_party/fpp'), |
| 643 ('trunk/src', 'src', self.FAKE_REPOS.svn_revs[1]), | 630 ('trunk/other@2', 'src/other'), |
| 644 ('trunk/third_party/foo', 'src/third_party/fpp', | 631 ('trunk/third_party/foo@2', 'src/third_party/prout'))) |
| 645 self.FAKE_REPOS.svn_revs[2]), | |
| 646 ('trunk/other', 'src/other', self.FAKE_REPOS.svn_revs[2]), | |
| 647 ('trunk/third_party/foo', 'src/third_party/prout', | |
| 648 self.FAKE_REPOS.svn_revs[2]), | |
| 649 )) | |
| 650 self.assertTree(tree) | 632 self.assertTree(tree) |
| 651 | 633 |
| 652 | 634 |
| 653 if __name__ == '__main__': | 635 if __name__ == '__main__': |
| 654 if '-c' in sys.argv: | 636 if '-c' in sys.argv: |
| 655 COVERAGE = True | 637 COVERAGE = True |
| 656 sys.argv.remove('-c') | 638 sys.argv.remove('-c') |
| 657 if os.path.exists('.coverage'): | 639 if os.path.exists('.coverage'): |
| 658 os.remove('.coverage') | 640 os.remove('.coverage') |
| 659 os.environ['COVERAGE_FILE'] = os.path.join( | 641 os.environ['COVERAGE_FILE'] = os.path.join( |
| 660 os.path.dirname(os.path.dirname(os.path.abspath(__file__))), | 642 os.path.dirname(os.path.dirname(os.path.abspath(__file__))), |
| 661 '.coverage') | 643 '.coverage') |
| 662 unittest.main() | 644 unittest.main() |
| OLD | NEW |