comparison tests/test_util.py @ 331:75f082b5897e

Switch to using url scheme wrappers instead of duplicating each command we wrap. The 'hg svn url' command has been killed; the replacement is '.hg/hgrc'. More stuff related to its disappearance has been stripped, including two tests. HgChangeReceiver now takes a UUID argument, which it uses to ensure that remote repositories remain unchanged. This is a temporary solution, and I'm not entirely satisfied with how it's done either. Access to the UUID file has been isolated in a HgChangeReceiver property. Some more tests have been updated to use ui.pushbuffer()/popbuffer(), and to pass through the Mercurial API. Moved the arguments to wrappers.pull() to the UI configuration. Also, remove HgChangeReceiver.opts in favour of a 'usebranchnames' instance & configuration variable. The name is taken from the ConvertExtension.
author Dan Villiom Podlaski Christiansen <danchr@gmail.com>
date Fri, 15 May 2009 19:18:43 +0200
parents 33736e2e25f0
children a59ab58969d9
comparison
equal deleted inserted replaced
330:5f8f2fd4fd54 331:75f082b5897e
7 import tempfile 7 import tempfile
8 import unittest 8 import unittest
9 import urllib 9 import urllib
10 10
11 from mercurial import context 11 from mercurial import context
12 from mercurial import commands
12 from mercurial import hg 13 from mercurial import hg
13 from mercurial import node 14 from mercurial import node
14 from mercurial import ui 15 from mercurial import ui
15
16 import wrappers
17 16
18 # Fixtures that need to be pulled at a subdirectory of the repo path 17 # Fixtures that need to be pulled at a subdirectory of the repo path
19 subdir = {'truncatedhistory.svndump': '/project2', 18 subdir = {'truncatedhistory.svndump': '/project2',
20 'fetch_missing_files_subdir.svndump': '/foo', 19 'fetch_missing_files_subdir.svndump': '/foo',
21 'empty_dir_in_trunk_not_repo_root.svndump': '/project', 20 'empty_dir_in_trunk_not_repo_root.svndump': '/project',
35 34
36 def load_svndump_fixture(path, fixture_name): 35 def load_svndump_fixture(path, fixture_name):
37 '''Loads an svnadmin dump into a fresh repo at path, which should not 36 '''Loads an svnadmin dump into a fresh repo at path, which should not
38 already exist. 37 already exist.
39 ''' 38 '''
40 subprocess.call(['svnadmin', 'create', path,]) 39 if os.path.exists(path): rmtree(path)
41 proc = subprocess.Popen(['svnadmin', 'load', path,], stdin=subprocess.PIPE, 40 subprocess.call(['svnadmin', 'create', path,],
41 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
42 inp = open(os.path.join(FIXTURES, fixture_name))
43 proc = subprocess.Popen(['svnadmin', 'load', path,], stdin=inp,
42 stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 44 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
43 inp = open(os.path.join(FIXTURES, fixture_name))
44 proc.stdin.write(inp.read())
45 proc.stdin.flush()
46 proc.communicate() 45 proc.communicate()
47 46
48 def load_fixture_and_fetch(fixture_name, repo_path, wc_path, stupid=False, subdir='', noupdate=True): 47 def load_fixture_and_fetch(fixture_name, repo_path, wc_path, stupid=False, subdir='', noupdate=True):
49 load_svndump_fixture(repo_path, fixture_name) 48 load_svndump_fixture(repo_path, fixture_name)
50 if subdir: 49 if subdir:
51 repo_path += '/' + subdir 50 repo_path += '/' + subdir
52 wrappers.clone(None, ui.ui(), source=fileurl(repo_path), 51
53 dest=wc_path, stupid=stupid, noupdate=noupdate) 52 _ui = ui.ui()
54 repo = hg.repository(ui.ui(), wc_path) 53 _ui.setconfig('hgsubversion', 'stupid', str(stupid))
55 return repo 54 commands.clone(_ui, fileurl(repo_path), wc_path, noupdate=noupdate)
55 _ui = ui.ui()
56 _ui.setconfig('hgsubversion', 'stupid', str(stupid))
57 return hg.repository(_ui, wc_path)
56 58
57 def rmtree(path): 59 def rmtree(path):
58 # Read-only files cannot be removed under Windows 60 # Read-only files cannot be removed under Windows
59 for root, dirs, files in os.walk(path): 61 for root, dirs, files in os.walk(path):
60 for f in files: 62 for f in files:
67 raise 69 raise
68 if (s.st_mode & stat.S_IWRITE) == 0: 70 if (s.st_mode & stat.S_IWRITE) == 0:
69 os.chmod(f, s.st_mode | stat.S_IWRITE) 71 os.chmod(f, s.st_mode | stat.S_IWRITE)
70 shutil.rmtree(path) 72 shutil.rmtree(path)
71 73
72
73 class MockUI(object):
74 real_ui = ui.ui
75 _isatty = False
76 def __init__(self, src=None):
77 self.stream = StringIO.StringIO()
78 self.inner_ui = self.real_ui(src)
79
80 def status(self, *args):
81 self.stream.write(''.join(args))
82
83 def warn(self, *args):
84 self.stream.write(*args)
85
86 def write(self, *args):
87 self.stream.write(*args)
88
89 def copy(self):
90 return self.__class__(self.inner_ui)
91
92 def __getattr__(self, attr):
93 return getattr(self.inner_ui, attr)
94
95
96 class TestBase(unittest.TestCase): 74 class TestBase(unittest.TestCase):
97 def setUp(self): 75 def setUp(self):
98 self.oldwd = os.getcwd() 76 self.oldwd = os.getcwd()
99 self.tmpdir = tempfile.mkdtemp( 77 self.tmpdir = tempfile.mkdtemp(
100 'svnwrap_test', dir=os.environ.get('HGSUBVERSION_TEST_TEMP', None)) 78 'svnwrap_test', dir=os.environ.get('HGSUBVERSION_TEST_TEMP', None))
103 rc = open(self.hgrc, 'w') 81 rc = open(self.hgrc, 'w')
104 rc.write('[extensions]\nhgsubversion=') 82 rc.write('[extensions]\nhgsubversion=')
105 83
106 self.repo_path = '%s/testrepo' % self.tmpdir 84 self.repo_path = '%s/testrepo' % self.tmpdir
107 self.wc_path = '%s/testrepo_wc' % self.tmpdir 85 self.wc_path = '%s/testrepo_wc' % self.tmpdir
108 self._real_ui = ui.ui 86
109 ui.ui = MockUI 87 # Previously, we had a MockUI class that wrapped ui, and giving access
88 # to the stream. The ui.pushbuffer() and ui.popbuffer() can be used
89 # instead. Using the regular UI class, with all stderr redirected to
90 # stdout ensures that the test setup is much more similar to usage
91 # setups.
92 self._ui_write_err = ui.ui.write_err
93 ui.ui.write_err = ui.ui.write
110 94
111 def tearDown(self): 95 def tearDown(self):
112 rmtree(self.tmpdir) 96 rmtree(self.tmpdir)
113 os.chdir(self.oldwd) 97 os.chdir(self.oldwd)
114 ui.ui = self._real_ui 98 ui.ui.write_err = self._ui_write_err
115 99
116 def _load_fixture_and_fetch(self, fixture_name, subdir='', stupid=False): 100 def _load_fixture_and_fetch(self, fixture_name, subdir='', stupid=False):
117 return load_fixture_and_fetch(fixture_name, self.repo_path, 101 return load_fixture_and_fetch(fixture_name, self.repo_path,
118 self.wc_path, subdir=subdir, 102 self.wc_path, subdir=subdir,
119 stupid=stupid) 103 stupid=stupid)
123 def repo(self): 107 def repo(self):
124 return hg.repository(ui.ui(), self.wc_path) 108 return hg.repository(ui.ui(), self.wc_path)
125 109
126 def pushrevisions(self, stupid=False): 110 def pushrevisions(self, stupid=False):
127 before = len(self.repo) 111 before = len(self.repo)
128 wrappers.push(None, ui.ui(), repo=self.repo, stupid=stupid) 112 self.repo.ui.setconfig('hgsubversion', 'stupid', str(stupid))
113 commands.push(self.repo.ui, self.repo)
129 after = len(self.repo) 114 after = len(self.repo)
130 self.assertEqual(0, after - before) 115 self.assertEqual(0, after - before)
131 116
132 def svnls(self, path, rev='HEAD'): 117 def svnls(self, path, rev='HEAD'):
133 path = self.repo_path + '/' + path 118 path = self.repo_path + '/' + path
134 path = fileurl(path) 119 path = fileurl(path)
135 args = ['svn', 'ls', '-r', rev, '-R', path] 120 args = ['svn', 'ls', '-r', rev, '-R', path]
136 p = subprocess.Popen(args, 121 p = subprocess.Popen(args,
137 stdout=subprocess.PIPE, 122 stdout=subprocess.PIPE,
138 stderr=subprocess.PIPE) 123 stderr=subprocess.STDOUT)
139 stdout, stderr = p.communicate() 124 stdout, stderr = p.communicate()
140 if p.returncode: 125 if p.returncode:
141 raise Exception('svn ls failed on %s: %r' % (path, stderr)) 126 raise Exception('svn ls failed on %s: %r' % (path, stderr))
142 entries = [e.strip('/') for e in stdout.splitlines()] 127 entries = [e.strip('/') for e in stdout.splitlines()]
143 entries.sort() 128 entries.sort()