blob: 5486fac803f0357ec8329a4d4544d9e5be5777a5 [file] [log] [blame]
[email protected]dfaecd22011-04-21 00:33:311#!/usr/bin/env python
[email protected]4f6852c2012-04-20 20:39:202# Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]dfaecd22011-04-21 00:33:313# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Unit tests for checkout.py."""
7
[email protected]dfaecd22011-04-21 00:33:318import logging
9import os
10import shutil
11import sys
12import unittest
13from xml.etree import ElementTree
14
15ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
[email protected]428342a2011-11-10 15:46:3316sys.path.insert(0, os.path.dirname(ROOT_DIR))
[email protected]dfaecd22011-04-21 00:33:3117
[email protected]0927b7e2011-11-11 16:06:2218from testing_support import fake_repos
19from testing_support.patches_data import GIT, RAW
20
[email protected]dfaecd22011-04-21 00:33:3121import checkout
22import patch
23import subprocess2
[email protected]dfaecd22011-04-21 00:33:3124
25
26# pass -v to enable it.
27DEBUGGING = False
28
[email protected]dfaecd22011-04-21 00:33:3129# A patch that will fail to apply.
[email protected]ce695142011-09-28 18:43:2530BAD_PATCH = ''.join(
31 [l for l in GIT.PATCH.splitlines(True) if l.strip() != 'e'])
[email protected]dfaecd22011-04-21 00:33:3132
33
34class FakeRepos(fake_repos.FakeReposBase):
35 def populateSvn(self):
36 """Creates a few revisions of changes files."""
37 subprocess2.check_call(
38 ['svn', 'checkout', self.svn_base, self.svn_checkout, '-q',
39 '--non-interactive', '--no-auth-cache',
40 '--username', self.USERS[0][0], '--password', self.USERS[0][1]])
41 assert os.path.isdir(os.path.join(self.svn_checkout, '.svn'))
[email protected]5e975632011-09-29 18:07:0642 self._commit_svn(self._tree_1())
43 self._commit_svn(self._tree_2())
44
45 @staticmethod
46 def _tree_1():
[email protected]dfaecd22011-04-21 00:33:3147 fs = {}
48 fs['trunk/origin'] = 'svn@1'
49 fs['trunk/codereview.settings'] = (
50 '# Test data\n'
51 'bar: pouet\n')
[email protected]ce695142011-09-28 18:43:2552 fs['trunk/chrome/file.cc'] = (
[email protected]dfaecd22011-04-21 00:33:3153 'a\n'
54 'bb\n'
55 'ccc\n'
56 'dd\n'
57 'e\n'
58 'ff\n'
59 'ggg\n'
60 'hh\n'
61 'i\n'
62 'jj\n'
63 'kkk\n'
64 'll\n'
65 'm\n'
66 'nn\n'
67 'ooo\n'
68 'pp\n'
69 'q\n')
[email protected]5e975632011-09-29 18:07:0670 return fs
71
72 @classmethod
73 def _tree_2(cls):
74 fs = cls._tree_1()
[email protected]dfaecd22011-04-21 00:33:3175 fs['trunk/origin'] = 'svn@2\n'
76 fs['trunk/extra'] = 'dummy\n'
77 fs['trunk/bin_file'] = '\x00'
[email protected]5e975632011-09-29 18:07:0678 fs['trunk/chromeos/views/DOMui_menu_widget.h'] = (
79 '// Copyright (c) 2010\n'
80 '// Use of this source code\n'
81 '// found in the LICENSE file.\n'
82 '\n'
83 '#ifndef DOM\n'
84 '#define DOM\n'
85 '#pragma once\n'
86 '\n'
87 '#include <string>\n'
88 '#endif\n')
89 return fs
[email protected]dfaecd22011-04-21 00:33:3190
91 def populateGit(self):
92 raise NotImplementedError()
93
94
95# pylint: disable=R0201
96class BaseTest(fake_repos.FakeReposTestBase):
97 name = 'foo'
98 FAKE_REPOS_CLASS = FakeRepos
[email protected]b1d1a782011-09-29 14:13:5599 is_read_only = False
[email protected]dfaecd22011-04-21 00:33:31100
101 def setUp(self):
102 # Need to enforce subversion_config first.
103 checkout.SvnMixIn.svn_config_dir = os.path.join(
104 ROOT_DIR, 'subversion_config')
105 super(BaseTest, self).setUp()
106 self._old_call = subprocess2.call
107 def redirect_call(args, **kwargs):
108 if not DEBUGGING:
109 kwargs.setdefault('stdout', subprocess2.PIPE)
110 kwargs.setdefault('stderr', subprocess2.STDOUT)
111 return self._old_call(args, **kwargs)
112 subprocess2.call = redirect_call
113 self.usr, self.pwd = self.FAKE_REPOS.USERS[0]
114 self.previous_log = None
115
116 def tearDown(self):
117 subprocess2.call = self._old_call
118 super(BaseTest, self).tearDown()
119
120 def get_patches(self):
121 return patch.PatchSet([
[email protected]5e975632011-09-29 18:07:06122 patch.FilePatchDiff('new_dir/subdir/new_file', GIT.NEW_SUBDIR, []),
123 patch.FilePatchDiff('chrome/file.cc', GIT.PATCH, []),
[email protected]97366be2011-06-03 20:02:46124 # TODO(maruel): Test with is_new == False.
125 patch.FilePatchBinary('bin_file', '\x00', [], is_new=True),
[email protected]dfaecd22011-04-21 00:33:31126 patch.FilePatchDelete('extra', False),
[email protected]dfaecd22011-04-21 00:33:31127 ])
128
129 def get_trunk(self, modified):
130 tree = {}
131 subroot = 'trunk/'
132 for k, v in self.FAKE_REPOS.svn_revs[-1].iteritems():
133 if k.startswith(subroot):
134 f = k[len(subroot):]
135 assert f not in tree
136 tree[f] = v
137
138 if modified:
[email protected]ce695142011-09-28 18:43:25139 content_lines = tree['chrome/file.cc'].splitlines(True)
140 tree['chrome/file.cc'] = ''.join(
[email protected]dfaecd22011-04-21 00:33:31141 content_lines[0:5] + ['FOO!\n'] + content_lines[5:])
142 del tree['extra']
143 tree['new_dir/subdir/new_file'] = 'A new file\nshould exist.\n'
144 return tree
145
146 def _check_base(self, co, root, git, expected):
147 read_only = isinstance(co, checkout.ReadOnlyCheckout)
[email protected]b1d1a782011-09-29 14:13:55148 self.assertEquals(not read_only, bool(expected))
149 self.assertEquals(read_only, self.is_read_only)
[email protected]dfaecd22011-04-21 00:33:31150 if not read_only:
151 self.FAKE_REPOS.svn_dirty = True
152
153 self.assertEquals(root, co.project_path)
[email protected]51919772011-06-12 01:27:42154 self.assertEquals(self.previous_log['revision'], co.prepare(None))
[email protected]dfaecd22011-04-21 00:33:31155 self.assertEquals('pouet', co.get_settings('bar'))
156 self.assertTree(self.get_trunk(False), root)
157 patches = self.get_patches()
158 co.apply_patch(patches)
159 self.assertEquals(
[email protected]ce695142011-09-28 18:43:25160 ['bin_file', 'chrome/file.cc', 'new_dir/subdir/new_file', 'extra'],
161 patches.filenames)
[email protected]dfaecd22011-04-21 00:33:31162
163 if git:
164 # Hackish to verify _branches() internal function.
165 # pylint: disable=W0212
166 self.assertEquals(
167 (['master', 'working_branch'], 'working_branch'),
[email protected]b1d1a782011-09-29 14:13:55168 co._branches())
[email protected]dfaecd22011-04-21 00:33:31169
170 # Verify that the patch is applied even for read only checkout.
171 self.assertTree(self.get_trunk(True), root)
172 fake_author = self.FAKE_REPOS.USERS[1][0]
[email protected]1bf50972011-05-05 19:57:21173 revision = co.commit(u'msg', fake_author)
[email protected]dfaecd22011-04-21 00:33:31174 # Nothing changed.
175 self.assertTree(self.get_trunk(True), root)
176
177 if read_only:
178 self.assertEquals('FAKE', revision)
[email protected]51919772011-06-12 01:27:42179 self.assertEquals(self.previous_log['revision'], co.prepare(None))
[email protected]dfaecd22011-04-21 00:33:31180 # Changes should be reverted now.
181 self.assertTree(self.get_trunk(False), root)
182 expected = self.previous_log
183 else:
184 self.assertEquals(self.previous_log['revision'] + 1, revision)
[email protected]51919772011-06-12 01:27:42185 self.assertEquals(self.previous_log['revision'] + 1, co.prepare(None))
[email protected]dfaecd22011-04-21 00:33:31186 self.assertTree(self.get_trunk(True), root)
187 expected = expected.copy()
188 expected['msg'] = 'msg'
189 expected['revision'] = self.previous_log['revision'] + 1
190 expected.setdefault('author', fake_author)
191
192 actual = self._log()
193 self.assertEquals(expected, actual)
194
195 def _check_exception(self, co, err_msg):
[email protected]51919772011-06-12 01:27:42196 co.prepare(None)
[email protected]dfaecd22011-04-21 00:33:31197 try:
[email protected]ce695142011-09-28 18:43:25198 co.apply_patch([patch.FilePatchDiff('chrome/file.cc', BAD_PATCH, [])])
[email protected]dfaecd22011-04-21 00:33:31199 self.fail()
200 except checkout.PatchApplicationFailed, e:
[email protected]ce695142011-09-28 18:43:25201 self.assertEquals(e.filename, 'chrome/file.cc')
[email protected]dfaecd22011-04-21 00:33:31202 self.assertEquals(e.status, err_msg)
203
204 def _log(self):
205 raise NotImplementedError()
206
[email protected]a5129fb2011-06-20 18:36:25207 def _test_process(self, co_lambda):
[email protected]8a1396c2011-04-22 00:14:24208 """Makes sure the process lambda is called correctly."""
[email protected]a5129fb2011-06-20 18:36:25209 post_processors = [lambda *args: results.append(args)]
210 co = co_lambda(post_processors)
211 self.assertEquals(post_processors, co.post_processors)
[email protected]51919772011-06-12 01:27:42212 co.prepare(None)
[email protected]8a1396c2011-04-22 00:14:24213 ps = self.get_patches()
214 results = []
[email protected]6ed8b502011-06-12 01:05:35215 co.apply_patch(ps)
[email protected]b1d1a782011-09-29 14:13:55216 expected_co = getattr(co, 'checkout', co)
217 # Because of ReadOnlyCheckout.
218 expected = [(expected_co, p) for p in ps.patches]
219 self.assertEquals(len(expected), len(results))
[email protected]8a1396c2011-04-22 00:14:24220 self.assertEquals(expected, results)
221
[email protected]5e975632011-09-29 18:07:06222 def _check_move(self, co):
223 """Makes sure file moves are handled correctly."""
224 co.prepare(None)
225 patchset = patch.PatchSet([
226 patch.FilePatchDelete('chromeos/views/DOMui_menu_widget.h', False),
227 patch.FilePatchDiff(
228 'chromeos/views/webui_menu_widget.h', GIT.RENAME_PARTIAL, []),
229 ])
230 co.apply_patch(patchset)
231 # Make sure chromeos/views/DOMui_menu_widget.h is deleted and
232 # chromeos/views/webui_menu_widget.h is correctly created.
233 root = os.path.join(self.root_dir, self.name)
234 tree = self.get_trunk(False)
235 del tree['chromeos/views/DOMui_menu_widget.h']
236 tree['chromeos/views/webui_menu_widget.h'] = (
237 '// Copyright (c) 2011\n'
238 '// Use of this source code\n'
239 '// found in the LICENSE file.\n'
240 '\n'
241 '#ifndef WEB\n'
242 '#define WEB\n'
243 '#pragma once\n'
244 '\n'
245 '#include <string>\n'
246 '#endif\n')
247 #print patchset[0].get()
248 #print fake_repos.read_tree(root)
249 self.assertTree(tree, root)
250
[email protected]dfaecd22011-04-21 00:33:31251
252class SvnBaseTest(BaseTest):
253 def setUp(self):
254 super(SvnBaseTest, self).setUp()
255 self.enabled = self.FAKE_REPOS.set_up_svn()
256 self.assertTrue(self.enabled)
257 self.svn_trunk = 'trunk'
258 self.svn_url = self.svn_base + self.svn_trunk
259 self.previous_log = self._log()
260
261 def _log(self):
262 # Don't use the local checkout in case of caching incorrency.
263 out = subprocess2.check_output(
264 ['svn', 'log', self.svn_url,
265 '--non-interactive', '--no-auth-cache',
266 '--username', self.usr, '--password', self.pwd,
267 '--with-all-revprops', '--xml',
268 '--limit', '1'])
269 logentry = ElementTree.XML(out).find('logentry')
270 if logentry == None:
271 return {'revision': 0}
272 data = {
273 'revision': int(logentry.attrib['revision']),
274 }
275 def set_item(name):
276 item = logentry.find(name)
277 if item != None:
278 data[name] = item.text
279 set_item('author')
280 set_item('msg')
281 revprops = logentry.find('revprops')
282 if revprops != None:
283 data['revprops'] = []
284 for prop in revprops.getiterator('property'):
285 data['revprops'].append((prop.attrib['name'], prop.text))
286 return data
287
[email protected]51919772011-06-12 01:27:42288 def _test_prepare(self, co):
289 self.assertEquals(1, co.prepare(1))
290
[email protected]dfaecd22011-04-21 00:33:31291
292class SvnCheckout(SvnBaseTest):
[email protected]b1d1a782011-09-29 14:13:55293 def _get_co(self, post_processors):
294 self.assertNotEqual(False, post_processors)
295 return checkout.SvnCheckout(
296 self.root_dir, self.name, self.usr, self.pwd, self.svn_url,
297 post_processors)
[email protected]dfaecd22011-04-21 00:33:31298
[email protected]b1d1a782011-09-29 14:13:55299 def testAll(self):
[email protected]dfaecd22011-04-21 00:33:31300 expected = {
301 'author': self.FAKE_REPOS.USERS[0][0],
302 'revprops': [('realauthor', self.FAKE_REPOS.USERS[1][0])]
303 }
[email protected]b1d1a782011-09-29 14:13:55304 root = os.path.join(self.root_dir, self.name)
305 self._check_base(self._get_co(None), root, False, expected)
[email protected]dfaecd22011-04-21 00:33:31306
307 def testException(self):
308 self._check_exception(
[email protected]b1d1a782011-09-29 14:13:55309 self._get_co(None),
[email protected]ec4a9182012-09-28 20:39:45310 'While running patch -p1 --forward --force --no-backup-if-mismatch;\n'
[email protected]4dd9f722012-10-01 16:23:03311 ' patching file chrome/file.cc\n'
312 ' Hunk #1 FAILED at 3.\n'
313 ' 1 out of 1 hunk FAILED -- saving rejects to file '
[email protected]ce695142011-09-28 18:43:25314 'chrome/file.cc.rej\n')
[email protected]dfaecd22011-04-21 00:33:31315
316 def testSvnProps(self):
[email protected]b1d1a782011-09-29 14:13:55317 co = self._get_co(None)
[email protected]51919772011-06-12 01:27:42318 co.prepare(None)
[email protected]dfaecd22011-04-21 00:33:31319 try:
320 # svn:ignore can only be applied to directories.
321 svn_props = [('svn:ignore', 'foo')]
322 co.apply_patch(
[email protected]ce695142011-09-28 18:43:25323 [patch.FilePatchDiff('chrome/file.cc', RAW.PATCH, svn_props)])
[email protected]dfaecd22011-04-21 00:33:31324 self.fail()
325 except checkout.PatchApplicationFailed, e:
[email protected]ce695142011-09-28 18:43:25326 self.assertEquals(e.filename, 'chrome/file.cc')
[email protected]dfaecd22011-04-21 00:33:31327 self.assertEquals(
328 e.status,
[email protected]ce695142011-09-28 18:43:25329 'While running svn propset svn:ignore foo chrome/file.cc '
[email protected]9842a0c2011-05-30 20:41:54330 '--non-interactive;\n'
[email protected]4dd9f722012-10-01 16:23:03331 ' patching file chrome/file.cc\n'
332 ' svn: Cannot set \'svn:ignore\' on a file (\'chrome/file.cc\')\n')
[email protected]51919772011-06-12 01:27:42333 co.prepare(None)
[email protected]dfaecd22011-04-21 00:33:31334 svn_props = [('svn:eol-style', 'LF'), ('foo', 'bar')]
335 co.apply_patch(
[email protected]ce695142011-09-28 18:43:25336 [patch.FilePatchDiff('chrome/file.cc', RAW.PATCH, svn_props)])
337 filepath = os.path.join(self.root_dir, self.name, 'chrome/file.cc')
[email protected]dfaecd22011-04-21 00:33:31338 # Manually verify the properties.
339 props = subprocess2.check_output(
340 ['svn', 'proplist', filepath],
341 cwd=self.root_dir).splitlines()[1:]
342 props = sorted(p.strip() for p in props)
343 expected_props = dict(svn_props)
344 self.assertEquals(sorted(expected_props.iterkeys()), props)
345 for k, v in expected_props.iteritems():
346 value = subprocess2.check_output(
347 ['svn', 'propget', '--strict', k, filepath],
348 cwd=self.root_dir).strip()
349 self.assertEquals(v, value)
350
351 def testWithRevPropsSupport(self):
352 # Add the hook that will commit in a way that removes the race condition.
353 hook = os.path.join(self.FAKE_REPOS.svn_repo, 'hooks', 'pre-commit')
354 shutil.copyfile(os.path.join(ROOT_DIR, 'sample_pre_commit_hook'), hook)
355 os.chmod(hook, 0755)
356 expected = {
357 'revprops': [('commit-bot', '[email protected]')],
358 }
[email protected]b1d1a782011-09-29 14:13:55359 root = os.path.join(self.root_dir, self.name)
360 self._check_base(self._get_co(None), root, False, expected)
[email protected]dfaecd22011-04-21 00:33:31361
362 def testWithRevPropsSupportNotCommitBot(self):
363 # Add the hook that will commit in a way that removes the race condition.
364 hook = os.path.join(self.FAKE_REPOS.svn_repo, 'hooks', 'pre-commit')
365 shutil.copyfile(os.path.join(ROOT_DIR, 'sample_pre_commit_hook'), hook)
366 os.chmod(hook, 0755)
367 co = checkout.SvnCheckout(
368 self.root_dir, self.name,
369 self.FAKE_REPOS.USERS[1][0], self.FAKE_REPOS.USERS[1][1],
370 self.svn_url)
371 root = os.path.join(self.root_dir, self.name)
372 expected = {
373 'author': self.FAKE_REPOS.USERS[1][0],
374 }
375 self._check_base(co, root, False, expected)
376
377 def testAutoProps(self):
[email protected]b1d1a782011-09-29 14:13:55378 co = self._get_co(None)
[email protected]dfaecd22011-04-21 00:33:31379 co.svn_config = checkout.SvnConfig(
380 os.path.join(ROOT_DIR, 'subversion_config'))
[email protected]51919772011-06-12 01:27:42381 co.prepare(None)
[email protected]dfaecd22011-04-21 00:33:31382 patches = self.get_patches()
383 co.apply_patch(patches)
384 self.assertEquals(
[email protected]ce695142011-09-28 18:43:25385 ['bin_file', 'chrome/file.cc', 'new_dir/subdir/new_file', 'extra'],
386 patches.filenames)
[email protected]dfaecd22011-04-21 00:33:31387 # *.txt = svn:eol-style=LF in subversion_config/config.
388 out = subprocess2.check_output(
[email protected]ce695142011-09-28 18:43:25389 ['svn', 'pget', 'svn:eol-style', 'chrome/file.cc'],
[email protected]dfaecd22011-04-21 00:33:31390 cwd=co.project_path)
391 self.assertEquals('LF\n', out)
392
[email protected]8a1396c2011-04-22 00:14:24393 def testProcess(self):
[email protected]b1d1a782011-09-29 14:13:55394 self._test_process(self._get_co)
[email protected]8a1396c2011-04-22 00:14:24395
[email protected]51919772011-06-12 01:27:42396 def testPrepare(self):
[email protected]b1d1a782011-09-29 14:13:55397 self._test_prepare(self._get_co(None))
[email protected]51919772011-06-12 01:27:42398
[email protected]5e975632011-09-29 18:07:06399 def testMove(self):
[email protected]3da83172012-05-07 16:17:20400 co = self._get_co(None)
401 self._check_move(co)
402 out = subprocess2.check_output(
403 ['svn', 'status'], cwd=co.project_path)
404 expected = (
405 'A + chromeos/views/webui_menu_widget.h\n'
406 'D chromeos/views/DOMui_menu_widget.h\n')
407 self.assertEquals(expected, out)
408 # Make sure ancestry is what is expected;
409 env = os.environ.copy()
410 env['LANGUAGE'] = 'en_US.UTF-8'
411 out = subprocess2.check_output(
412 ['svn', 'info', 'chromeos/views/webui_menu_widget.h'],
413 cwd=co.project_path,
414 env=env)
415 values = dict(l.split(': ', 1) for l in out.splitlines() if l)
416 expected = {
417 'Checksum': '65837bb3da662c8fa88a4a50940ea7c6',
418 'Copied From Rev': '2',
419 'Copied From URL':
420 '%strunk/chromeos/views/DOMui_menu_widget.h' % self.svn_base,
421 'Name': 'webui_menu_widget.h',
422 'Node Kind': 'file',
423 'Path': 'chromeos/views/webui_menu_widget.h',
424 'Repository Root': '%s' % self.svn_base.rstrip('/'),
425 'Revision': '2',
426 'Schedule': 'add',
427 'URL': '%strunk/chromeos/views/webui_menu_widget.h' % self.svn_base,
428 }
429 self.assertEquals(expected, values)
[email protected]5e975632011-09-29 18:07:06430
[email protected]dfaecd22011-04-21 00:33:31431
[email protected]dfaecd22011-04-21 00:33:31432class RawCheckout(SvnBaseTest):
433 def setUp(self):
434 super(RawCheckout, self).setUp()
435 # Use a svn checkout as the base.
436 self.base_co = checkout.SvnCheckout(
437 self.root_dir, self.name, None, None, self.svn_url)
[email protected]51919772011-06-12 01:27:42438 self.base_co.prepare(None)
[email protected]dfaecd22011-04-21 00:33:31439
[email protected]b1d1a782011-09-29 14:13:55440 def _get_co(self, post_processors):
441 self.assertNotEqual(False, post_processors)
442 return checkout.RawCheckout(self.root_dir, self.name, post_processors)
[email protected]dfaecd22011-04-21 00:33:31443
[email protected]b1d1a782011-09-29 14:13:55444 def testAll(self):
445 # Can't use self._check_base() since it's too different.
[email protected]dfaecd22011-04-21 00:33:31446 root = os.path.join(self.root_dir, self.name)
[email protected]b1d1a782011-09-29 14:13:55447 co = self._get_co(None)
[email protected]dfaecd22011-04-21 00:33:31448
449 # A copy of BaseTest._check_base()
450 self.assertEquals(root, co.project_path)
[email protected]51919772011-06-12 01:27:42451 self.assertEquals(None, co.prepare(None))
[email protected]dfaecd22011-04-21 00:33:31452 self.assertEquals('pouet', co.get_settings('bar'))
453 self.assertTree(self.get_trunk(False), root)
454 patches = self.get_patches()
455 co.apply_patch(patches)
456 self.assertEquals(
[email protected]ce695142011-09-28 18:43:25457 ['bin_file', 'chrome/file.cc', 'new_dir/subdir/new_file', 'extra'],
458 patches.filenames)
[email protected]dfaecd22011-04-21 00:33:31459
460 # Verify that the patch is applied even for read only checkout.
461 self.assertTree(self.get_trunk(True), root)
[email protected]b1d1a782011-09-29 14:13:55462 try:
463 co.commit(u'msg', self.FAKE_REPOS.USERS[1][0])
464 self.fail()
465 except NotImplementedError:
466 pass
[email protected]dfaecd22011-04-21 00:33:31467 self.assertTree(self.get_trunk(True), root)
468 # Verify that prepare() is a no-op.
[email protected]51919772011-06-12 01:27:42469 self.assertEquals(None, co.prepare(None))
[email protected]dfaecd22011-04-21 00:33:31470 self.assertTree(self.get_trunk(True), root)
471
[email protected]dfaecd22011-04-21 00:33:31472 def testException(self):
473 self._check_exception(
[email protected]b1d1a782011-09-29 14:13:55474 self._get_co(None),
[email protected]4dd9f722012-10-01 16:23:03475 'While running patch -u --binary -p1;\n'
476 ' patching file chrome/file.cc\n'
477 ' Hunk #1 FAILED at 3.\n'
478 ' 1 out of 1 hunk FAILED -- saving rejects to file '
[email protected]ce695142011-09-28 18:43:25479 'chrome/file.cc.rej\n')
[email protected]dfaecd22011-04-21 00:33:31480
[email protected]8a1396c2011-04-22 00:14:24481 def testProcess(self):
[email protected]b1d1a782011-09-29 14:13:55482 self._test_process(self._get_co)
[email protected]8a1396c2011-04-22 00:14:24483
[email protected]51919772011-06-12 01:27:42484 def testPrepare(self):
[email protected]b1d1a782011-09-29 14:13:55485 # RawCheckout doesn't support prepare() but emulate it.
486 co = self._get_co(None)
487 revs = [1]
488 def prepare(asked):
489 self.assertEquals(1, asked)
490 return revs.pop(0)
491 co.prepare = prepare
[email protected]51919772011-06-12 01:27:42492 self._test_prepare(co)
[email protected]b1d1a782011-09-29 14:13:55493 self.assertEquals([], revs)
494
[email protected]5e975632011-09-29 18:07:06495 def testMove(self):
496 self._check_move(self._get_co(None))
497
[email protected]b1d1a782011-09-29 14:13:55498
499class ReadOnlyCheckout(SvnBaseTest):
500 # Use SvnCheckout as the backed since it support read-only checkouts too.
501 is_read_only = True
502
503 def _get_co(self, post_processors):
504 self.assertNotEqual(False, post_processors)
505 return checkout.ReadOnlyCheckout(
506 checkout.SvnCheckout(
507 self.root_dir, self.name, None, None, self.svn_url, None),
508 post_processors)
509
510 def testAll(self):
511 root = os.path.join(self.root_dir, self.name)
512 self._check_base(self._get_co(None), root, False, None)
513
514 def testException(self):
515 self._check_exception(
516 self._get_co(None),
[email protected]ec4a9182012-09-28 20:39:45517 'While running patch -p1 --forward --force --no-backup-if-mismatch;\n'
[email protected]4dd9f722012-10-01 16:23:03518 ' patching file chrome/file.cc\n'
519 ' Hunk #1 FAILED at 3.\n'
520 ' 1 out of 1 hunk FAILED -- saving rejects to file '
[email protected]b1d1a782011-09-29 14:13:55521 'chrome/file.cc.rej\n')
522
523 def testProcess(self):
524 self._test_process(self._get_co)
525
526 def testPrepare(self):
527 self._test_prepare(self._get_co(None))
[email protected]51919772011-06-12 01:27:42528
[email protected]5e975632011-09-29 18:07:06529 def testMove(self):
530 self._check_move(self._get_co(None))
531
[email protected]dfaecd22011-04-21 00:33:31532
533if __name__ == '__main__':
534 if '-v' in sys.argv:
535 DEBUGGING = True
536 logging.basicConfig(
537 level=logging.DEBUG,
538 format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s')
539 else:
540 logging.basicConfig(
541 level=logging.ERROR,
542 format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s')
543 unittest.main()