summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorTristan Seligmann <mithrandi@debian.org>2017-08-11 09:51:59 +0000
committerTristan Seligmann <mithrandi@debian.org>2017-08-11 09:51:59 +0000
commita234ef0228929919399bc8adad6f8d8bb8dee7bc (patch)
tree4f9185baa7e0e6d37529ae2072e1c970244f6e14 /tests
parentb7339d75dcc99eeba499b376700e9e5ff545baff (diff)
parentf505a84d33c238a892064774ca31854d3b5b1df2 (diff)
New upstream version (hg snapshot).
Diffstat (limited to 'tests')
-rw-r--r--tests/comprehensive/test_obsstore_on.py40
-rw-r--r--tests/comprehensive/test_rebuildmeta.py17
-rw-r--r--tests/comprehensive/test_sqlite_revmap.py77
-rw-r--r--tests/comprehensive/test_verify_and_startrev.py1
-rw-r--r--tests/fixtures/dir_removal.svndump103
-rw-r--r--tests/fixtures/rename-closed-branch-dir.sh69
-rw-r--r--tests/fixtures/rename-closed-branch-dir.svndump296
-rwxr-xr-xtests/run.py82
-rw-r--r--tests/test_fetch_branches.py3
-rw-r--r--tests/test_fetch_command.py2
-rw-r--r--tests/test_fetch_dir_removal.py17
-rw-r--r--tests/test_fetch_mappings.py51
-rw-r--r--tests/test_fetch_renames.py33
-rw-r--r--tests/test_helpers.py1
-rw-r--r--tests/test_hooks.py2
-rw-r--r--tests/test_pull.py16
-rw-r--r--tests/test_pull_fallback.py4
-rw-r--r--tests/test_push_command.py30
-rw-r--r--tests/test_revmap_migrate.py72
-rw-r--r--tests/test_svnwrap.py14
-rw-r--r--tests/test_tags.py13
-rw-r--r--tests/test_urls.py55
-rw-r--r--tests/test_util.py62
-rw-r--r--tests/test_utility_commands.py6
24 files changed, 911 insertions, 155 deletions
diff --git a/tests/comprehensive/test_obsstore_on.py b/tests/comprehensive/test_obsstore_on.py
new file mode 100644
index 0000000..7fd4a25
--- /dev/null
+++ b/tests/comprehensive/test_obsstore_on.py
@@ -0,0 +1,40 @@
+import os
+import sys
+
+# wrapped in a try/except because of weirdness in how
+# run.py works as compared to nose.
+try:
+ import test_util
+except ImportError:
+ sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+ import test_util
+
+import test_push_command
+
+
+class ObsstoreOnMixIn(object):
+ # do not double the test size by being wrapped again
+ obsolete_mode_tests = False
+ stupid_mode_tests = False
+
+ def setUp(self):
+ super(ObsstoreOnMixIn, self).setUp()
+ hgrcpath = os.environ.get('HGRCPATH')
+ assert hgrcpath
+ with open(hgrcpath, 'a') as f:
+ f.write('\n[experimental]\nevolution=createmarkers\n')
+
+ def shortDescription(self):
+ text = super(ObsstoreOnMixIn, self).shortDescription()
+ if text:
+ text += ' (obsstore on)'
+ return text
+
+
+def buildtestclass(cls):
+ name = 'ObsstoreOn%s' % cls.__name__
+ newcls = type(name, (ObsstoreOnMixIn, cls,), {})
+ globals()[name] = newcls
+
+
+buildtestclass(test_push_command.PushTests)
diff --git a/tests/comprehensive/test_rebuildmeta.py b/tests/comprehensive/test_rebuildmeta.py
index e4e486b..e05f712 100644
--- a/tests/comprehensive/test_rebuildmeta.py
+++ b/tests/comprehensive/test_rebuildmeta.py
@@ -129,10 +129,14 @@ def _run_assertions(self, name, single, src, dest, u):
old, new = util.load(stf, resave=False), util.load(dtf, resave=False)
if tf == 'lastpulled' and (name,
self.stupid, single) in expect_youngest_skew:
- self.assertNotEqual(old, new,
- 'rebuildmeta unexpected match on youngest rev!')
+ self.assertNotEqual(
+ old, new,
+ 'rebuildmeta unexpected match on lastpulled: '
+ 'old %d new %d, case %r %r %r' % (
+ old, new, name, self.stupid, single))
continue
- self.assertEqual(old, new, tf + ' differs')
+ self.assertEqual(
+ old, new, '%s differs old: %r new %r'% (tf, old, new))
try:
self.assertEqual(src.branchmap(), dest.branchmap())
except AttributeError:
@@ -141,7 +145,12 @@ def _run_assertions(self, name, single, src, dest, u):
srcbi = util.load(os.path.join(src.path, 'svn', 'branch_info'))
destbi = util.load(os.path.join(dest.path, 'svn', 'branch_info'))
self.assertEqual(sorted(srcbi.keys()), sorted(destbi.keys()))
- revkeys = svnmeta.SVNMeta(dest).revmap.keys()
+ revmap = svnmeta.SVNMeta(dest).revmap
+ # revmap disables __iter__ intentionally to avoid possible slow code
+ # (not using database index in SqliteRevMap)
+ # we need to fetch all keys so enable it by setting _allowiter
+ revmap._allowiter = True
+ revkeys = revmap.keys()
for branch in destbi:
srcinfo = srcbi[branch]
destinfo = destbi[branch]
diff --git a/tests/comprehensive/test_sqlite_revmap.py b/tests/comprehensive/test_sqlite_revmap.py
new file mode 100644
index 0000000..0c0f2ec
--- /dev/null
+++ b/tests/comprehensive/test_sqlite_revmap.py
@@ -0,0 +1,77 @@
+import os
+import unittest
+import sys
+
+# wrapped in a try/except because of weirdness in how
+# run.py works as compared to nose.
+try:
+ import test_util
+except ImportError:
+ sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+ import test_util
+
+# interesting and fast tests
+import test_fetch_mappings
+import test_fetch_renames
+import test_pull
+import test_template_keywords
+import test_utility_commands
+
+# comprehensive tests
+try:
+ import test_custom_layout
+except ImportError:
+ sys.path.insert(0, os.path.dirname(__file__))
+ import test_custom_layout
+
+import test_rebuildmeta
+import test_updatemeta
+
+from hgsubversion import svnmeta, maps
+
+
+class SqliteRevMapMixIn(object):
+ # do not double the test size by being wrapped again
+ obsolete_mode_tests = False
+ stupid_mode_tests = False
+
+ def setUp(self):
+ assert svnmeta.SVNMeta._defaultrevmapclass is maps.RevMap
+ svnmeta.SVNMeta._defaultrevmapclass = maps.SqliteRevMap
+ super(SqliteRevMapMixIn, self).setUp()
+
+ def tearDown(self):
+ assert svnmeta.SVNMeta._defaultrevmapclass is maps.SqliteRevMap
+ svnmeta.SVNMeta._defaultrevmapclass = maps.RevMap
+ super(SqliteRevMapMixIn, self).tearDown()
+
+ def shortDescription(self):
+ text = super(SqliteRevMapMixIn, self).shortDescription()
+ if text:
+ text += ' (sqlite revmap)'
+ return text
+
+def buildtestclass(cls, selector=None):
+ name = 'SqliteRevMap%s' % cls.__name__
+ newcls = type(name, (SqliteRevMapMixIn, cls,), {})
+
+ # remove test cases not selected by selector
+ if selector:
+ for name in dir(newcls):
+ if name.startswith('test_') and not selector(name[5:]):
+ setattr(newcls, name, None)
+
+ globals()[name] = newcls
+
+def svndumpselector(name):
+ return name in ['branch_rename_to_trunk',
+ 'tag_name_same_as_branch']
+
+buildtestclass(test_fetch_mappings.MapTests)
+buildtestclass(test_fetch_renames.TestFetchRenames)
+buildtestclass(test_pull.TestPull)
+buildtestclass(test_template_keywords.TestLogKeywords)
+buildtestclass(test_utility_commands.UtilityTests)
+
+buildtestclass(test_rebuildmeta.RebuildMetaTests, svndumpselector)
+buildtestclass(test_updatemeta.UpdateMetaTests, svndumpselector)
diff --git a/tests/comprehensive/test_verify_and_startrev.py b/tests/comprehensive/test_verify_and_startrev.py
index 7581df0..8ad22c2 100644
--- a/tests/comprehensive/test_verify_and_startrev.py
+++ b/tests/comprehensive/test_verify_and_startrev.py
@@ -34,6 +34,7 @@ _skipstandard = set([
'correct.svndump',
'corrupt.svndump',
'emptyrepo2.svndump',
+ 'dir_removal.svndump',
])
def _do_case(self, name, layout):
diff --git a/tests/fixtures/dir_removal.svndump b/tests/fixtures/dir_removal.svndump
new file mode 100644
index 0000000..a278802
--- /dev/null
+++ b/tests/fixtures/dir_removal.svndump
@@ -0,0 +1,103 @@
+SVN-fs-dump-format-version: 2
+
+UUID: 5554378f-55cc-437f-9045-6148f657307d
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2017-05-23T11:48:49.399395Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 103
+Content-length: 103
+
+K 10
+svn:author
+V 8
+testuser
+K 8
+svn:date
+V 27
+2017-05-23T11:49:53.974692Z
+K 7
+svn:log
+V 1
+1
+PROPS-END
+
+Node-path: dir1
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: dir1/1.txt
+Node-kind: file
+Node-action: add
+Text-content-md5: d41d8cd98f00b204e9800998ecf8427e
+Text-content-sha1: da39a3ee5e6b4b0d3255bfef95601890afd80709
+Prop-content-length: 10
+Text-content-length: 0
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: dir2
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: dir2/2.txt
+Node-kind: file
+Node-action: add
+Text-content-md5: d41d8cd98f00b204e9800998ecf8427e
+Text-content-sha1: da39a3ee5e6b4b0d3255bfef95601890afd80709
+Prop-content-length: 10
+Text-content-length: 0
+Content-length: 10
+
+PROPS-END
+
+
+Revision-number: 2
+Prop-content-length: 103
+Content-length: 103
+
+K 10
+svn:author
+V 8
+testuser
+K 8
+svn:date
+V 27
+2017-05-23T11:50:14.852941Z
+K 7
+svn:log
+V 1
+2
+PROPS-END
+
+Node-path: dir1/dir2
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 1
+Node-copyfrom-path: dir2
+
+
+Node-path: dir2
+Node-action: delete
+
+
diff --git a/tests/fixtures/rename-closed-branch-dir.sh b/tests/fixtures/rename-closed-branch-dir.sh
new file mode 100644
index 0000000..d0ae264
--- /dev/null
+++ b/tests/fixtures/rename-closed-branch-dir.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+#
+# Generate rename-closed-branch-dir.svndump
+#
+
+mkdir temp
+cd temp
+
+mkdir project
+cd project
+mkdir trunk
+mkdir branches
+mkdir tags
+cd ..
+
+svnadmin create testrepo
+CURRENT_DIR=`pwd`
+svnurl=file://"$CURRENT_DIR"/testrepo
+#svn import project-orig $svnurl -m "init project"
+
+svn co $svnurl project
+cd project
+svn add *
+svn ci -m "init project"
+
+cd trunk
+echo a > a.txt
+svn add a.txt
+svn ci -m "add a.txt in trunk"
+
+# Create a branch
+svn up
+cd ../branches
+svn copy ../trunk async-db
+svn ci -m "add branch async-db"
+svn up
+
+# Implement feature
+cd async-db
+echo b > b.txt
+svn add b.txt
+svn ci -m "Async functionality"
+
+# Merge feature branch
+cd ../../trunk
+svn merge $svnurl/branches/async-db
+svn ci -m "Merged branch async-db"
+cd ..
+svn up
+
+# Create branch folder for unnecessary branches
+svn mkdir $svnurl/branches/dead -m "Create branch folder for unnecessary branches"
+svn up
+
+# We don't need the 'async-db' branch, anymore.
+svn copy $svnurl/branches/async-db $svnurl/branches/dead -m "We don't need the 'async-db' branch, anymore."
+svn up
+
+# Rename 'dead' folder to 'closed'
+svn move $svnurl/branches/dead $svnurl/branches/closed -m "Renamed 'dead' folder to 'closed'"
+svn up
+
+# Move 'branches/closed' to 'tags/closed'
+svn move $svnurl/branches/closed $svnurl/tags/closed -m "Moved 'branches/closed' to 'tags/closed'."
+svn up
+
+# Dump repository
+cd ..
+svnadmin dump testrepo > ../rename-closed-branch-dir.svndump
diff --git a/tests/fixtures/rename-closed-branch-dir.svndump b/tests/fixtures/rename-closed-branch-dir.svndump
new file mode 100644
index 0000000..aa327fe
--- /dev/null
+++ b/tests/fixtures/rename-closed-branch-dir.svndump
@@ -0,0 +1,296 @@
+SVN-fs-dump-format-version: 2
+
+UUID: 2efdcfe9-9dfd-40a7-a9cc-bf5b70806ff3
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2016-01-27T15:35:29.673334Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 112
+Content-length: 112
+
+K 10
+svn:author
+V 5
+augie
+K 8
+svn:date
+V 27
+2016-01-27T15:35:30.079847Z
+K 7
+svn:log
+V 12
+init project
+PROPS-END
+
+Node-path: branches
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: tags
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: trunk
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Revision-number: 2
+Prop-content-length: 118
+Content-length: 118
+
+K 10
+svn:author
+V 5
+augie
+K 8
+svn:date
+V 27
+2016-01-27T15:35:31.065912Z
+K 7
+svn:log
+V 18
+add a.txt in trunk
+PROPS-END
+
+Node-path: trunk/a.txt
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2
+Text-content-md5: 60b725f10c9c85c70d97880dfe8191b3
+Text-content-sha1: 3f786850e387550fdab836ed7e6dc881de23001b
+Content-length: 12
+
+PROPS-END
+a
+
+
+Revision-number: 3
+Prop-content-length: 119
+Content-length: 119
+
+K 10
+svn:author
+V 5
+augie
+K 8
+svn:date
+V 27
+2016-01-27T15:35:34.051261Z
+K 7
+svn:log
+V 19
+add branch async-db
+PROPS-END
+
+Node-path: branches/async-db
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 2
+Node-copyfrom-path: trunk
+
+
+Revision-number: 4
+Prop-content-length: 119
+Content-length: 119
+
+K 10
+svn:author
+V 5
+augie
+K 8
+svn:date
+V 27
+2016-01-27T15:35:36.101507Z
+K 7
+svn:log
+V 19
+Async functionality
+PROPS-END
+
+Node-path: branches/async-db/b.txt
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 2
+Text-content-md5: 3b5d5c3712955042212316173ccf37be
+Text-content-sha1: 89e6c98d92887913cadf06b2adb97f26cde4849b
+Content-length: 12
+
+PROPS-END
+b
+
+
+Revision-number: 5
+Prop-content-length: 122
+Content-length: 122
+
+K 10
+svn:author
+V 5
+augie
+K 8
+svn:date
+V 27
+2016-01-27T15:35:38.055736Z
+K 7
+svn:log
+V 22
+Merged branch async-db
+PROPS-END
+
+Node-path: trunk
+Node-kind: dir
+Node-action: change
+Prop-content-length: 57
+Content-length: 57
+
+K 13
+svn:mergeinfo
+V 22
+/branches/async-db:3-4
+PROPS-END
+
+
+Node-path: trunk/b.txt
+Node-kind: file
+Node-action: add
+Node-copyfrom-rev: 4
+Node-copyfrom-path: branches/async-db/b.txt
+Text-copy-source-md5: 3b5d5c3712955042212316173ccf37be
+Text-copy-source-sha1: 89e6c98d92887913cadf06b2adb97f26cde4849b
+
+
+Revision-number: 6
+Prop-content-length: 145
+Content-length: 145
+
+K 10
+svn:author
+V 5
+augie
+K 8
+svn:date
+V 27
+2016-01-27T15:35:40.046670Z
+K 7
+svn:log
+V 45
+Create branch folder for unnecessary branches
+PROPS-END
+
+Node-path: branches/dead
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Revision-number: 7
+Prop-content-length: 145
+Content-length: 145
+
+K 10
+svn:author
+V 5
+augie
+K 8
+svn:date
+V 27
+2016-01-27T15:35:41.048576Z
+K 7
+svn:log
+V 45
+We don't need the 'async-db' branch, anymore.
+PROPS-END
+
+Node-path: branches/dead/async-db
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 6
+Node-copyfrom-path: branches/async-db
+
+
+Revision-number: 8
+Prop-content-length: 133
+Content-length: 133
+
+K 10
+svn:author
+V 5
+augie
+K 8
+svn:date
+V 27
+2016-01-27T15:35:42.046536Z
+K 7
+svn:log
+V 33
+Renamed 'dead' folder to 'closed'
+PROPS-END
+
+Node-path: branches/closed
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 7
+Node-copyfrom-path: branches/dead
+
+
+Node-path: branches/dead
+Node-action: delete
+
+
+Revision-number: 9
+Prop-content-length: 141
+Content-length: 141
+
+K 10
+svn:author
+V 5
+augie
+K 8
+svn:date
+V 27
+2016-01-27T15:35:43.048056Z
+K 7
+svn:log
+V 41
+Moved 'branches/closed' to 'tags/closed'.
+PROPS-END
+
+Node-path: branches/closed
+Node-action: delete
+
+
+Node-path: tags/closed
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 8
+Node-copyfrom-path: branches/closed
+
+
diff --git a/tests/run.py b/tests/run.py
index aef61f9..497f4f2 100755
--- a/tests/run.py
+++ b/tests/run.py
@@ -5,53 +5,6 @@ import os
import sys
import unittest
-import test_util
-test_util.SkipTest = None
-
-def tests():
- import test_binaryfiles
- import test_diff
- import test_externals
- import test_fetch_branches
- import test_fetch_command
- import test_fetch_command_regexes
- import test_fetch_exec
- import test_fetch_mappings
- import test_fetch_renames
- import test_fetch_symlinks
- import test_fetch_truncated
- import test_hooks
- import test_svn_pre_commit_hooks
- import test_pull
- import test_pull_fallback
- import test_push_command
- import test_push_renames
- import test_push_dirs
- import test_push_eol
- import test_push_autoprops
- import test_single_dir_clone
- import test_single_dir_push
- import test_svnwrap
- import test_tags
- import test_template_keywords
- import test_utility_commands
- import test_unaffected_core
- import test_urls
-
- sys.path.append(os.path.dirname(__file__))
- sys.path.append(os.path.join(os.path.dirname(__file__), 'comprehensive'))
-
- import test_rebuildmeta
- import test_stupid_pull
- import test_updatemeta
- import test_verify_and_startrev
-
- return locals()
-
-def comprehensive(mod):
- dir = os.path.basename(os.path.dirname(mod.__file__))
- return dir == 'comprehensive'
-
if __name__ == '__main__':
description = ("This script runs the hgsubversion tests. If no tests are "
"specified, all known tests are implied.")
@@ -100,26 +53,33 @@ if __name__ == '__main__':
import tempfile
sys.stdout = tempfile.TemporaryFile()
- all_tests = tests()
-
- args = [i.split('.py')[0].replace('-', '_') for i in args]
+ args = [os.path.basename(os.path.splitext(arg)[0]).replace('-', '_')
+ for arg in args]
loader = unittest.TestLoader()
suite = unittest.TestSuite()
+ if sys.version_info[:2] < (2, 7):
+ import glob
+ def discover(start_dir, pattern='test*.py', top_level_dir=None):
+ tests = []
+ sys.path.append(start_dir)
+ for path in glob.glob(os.path.join(start_dir, pattern)):
+ name = os.path.splitext(os.path.basename(path))[0]
+ tests.append(loader.loadTestsFromModule(__import__(name)))
+ return tests
+ loader.discover = discover
+
if not args:
- check = lambda x: options.comprehensive or not comprehensive(x)
- suite.addTests(loader.loadTestsFromModule(m)
- for (n, m) in sorted(all_tests.iteritems())
- if check(m))
+ suite.addTests(loader.discover('.'))
+
+ if options.comprehensive:
+ suite.addTests(loader.discover('comprehensive',
+ top_level_dir='comprehensive'))
else:
- for arg in args:
- if arg == 'test_util':
- continue
- elif arg not in all_tests:
- print >> sys.stderr, 'test module %s not available' % arg
- else:
- suite.addTest(loader.loadTestsFromModule(all_tests[arg]))
+ sys.path.append(os.path.join(os.path.dirname(__file__), 'comprehensive'))
+
+ suite.addTests(loader.loadTestsFromNames(args))
runner = unittest.TextTestRunner(**testargs)
result = runner.run(suite)
diff --git a/tests/test_fetch_branches.py b/tests/test_fetch_branches.py
index 45991ae..781f023 100644
--- a/tests/test_fetch_branches.py
+++ b/tests/test_fetch_branches.py
@@ -41,7 +41,8 @@ class TestFetchBranches(test_util.TestBase):
heads = dict([(ctx.branch(), ctx) for ctx in heads])
# Let these tests disabled yet as the fix is not obvious
self.assertEqual(heads['branch1'].manifest().keys(), ['b'])
- self.assertEqual(heads['branch2'].manifest().keys(), ['a', 'b'])
+ self.assertEqual(sorted(heads['branch2'].manifest().keys()),
+ ['a', 'b'])
def test_unorderedbranch(self):
repo = self._load_fixture_and_fetch('unorderedbranch.svndump')
diff --git a/tests/test_fetch_command.py b/tests/test_fetch_command.py
index 4649555..745a4a4 100644
--- a/tests/test_fetch_command.py
+++ b/tests/test_fetch_command.py
@@ -93,7 +93,7 @@ class TestBasicRepoLayout(test_util.TestBase):
'test_files_copied_from_outside_btt.svndump')
self.assertEqual(node.hex(repo['tip'].node()),
'3c78170e30ddd35f2c32faa0d8646ab75bba4f73')
- self.assertEqual(test_util.repolen(repo.changelog), 2)
+ self.assertEqual(test_util.repolen(repo), 2)
def test_file_renamed_in_from_outside_btt(self):
repo = self._load_fixture_and_fetch(
diff --git a/tests/test_fetch_dir_removal.py b/tests/test_fetch_dir_removal.py
new file mode 100644
index 0000000..24a795d
--- /dev/null
+++ b/tests/test_fetch_dir_removal.py
@@ -0,0 +1,17 @@
+import test_util
+
+import sys
+import unittest
+
+class TestFetchDirectoryRemoval(test_util.TestBase):
+ stupid_mode_tests = True
+
+ def test_removal(self):
+ repo = self._load_fixture_and_fetch('dir_removal.svndump',
+ layout='single',
+ subdir='dir1')
+ self.assertEqual(sorted(repo['tip'].manifest().keys()),
+ ['1.txt', 'dir2/2.txt'])
+ extra = repo['tip'].extra().copy()
+ extra.pop('convert_revision', None)
+ self.assertEqual(extra, {'branch': 'default'})
diff --git a/tests/test_fetch_mappings.py b/tests/test_fetch_mappings.py
index f022c6f..f4e373c 100644
--- a/tests/test_fetch_mappings.py
+++ b/tests/test_fetch_mappings.py
@@ -92,7 +92,10 @@ class MapTests(test_util.TestBase):
new = open(os.path.join(repopath, 'authors'), 'w')
new.write(open(orig).read())
new.close()
- test = maps.AuthorMap(self.repo.svnmeta(skiperrorcheck=True))
+ meta = self.repo.svnmeta(skiperrorcheck=True)
+ test = maps.AuthorMap(
+ meta.ui, meta.authormap_file, meta.defaulthost,
+ meta.caseignoreauthors, meta.mapauthorscmd, meta.defaultauthors)
fromself = set(test)
test.load(orig)
all_tests = set(test)
@@ -114,6 +117,15 @@ class MapTests(test_util.TestBase):
self.assertEqual(self.repo['tip'].user(),
'evil@5b65bade-98f3-4993-a01f-b7a6710da339')
+ def test_author_map_mapauthorscmd(self):
+ repo_path = self.load_svndump('replace_trunk_with_branch.svndump')
+ ui = self.ui()
+ ui.setconfig('hgsubversion', 'mapauthorscmd', 'echo "svn: %s"')
+ commands.clone(ui, test_util.fileurl(repo_path),
+ self.wc_path)
+ self.assertEqual(self.repo[0].user(), 'svn: Augie')
+ self.assertEqual(self.repo['tip'].user(), 'svn: evil')
+
def _loadwithfilemap(self, svndump, filemapcontent,
failonmissing=True):
repo_path = self.load_svndump(svndump)
@@ -149,9 +161,9 @@ class MapTests(test_util.TestBase):
# The exclusion of alpha is overridden by the later rule to
# include all of '.', whereas gamma should remain excluded
# because it's excluded after the root directory.
- self.assertEqual(self.repo[0].manifest().keys(),
+ self.assertEqual(sorted(self.repo[0].manifest().keys()),
['alpha', 'beta'])
- self.assertEqual(self.repo['default'].manifest().keys(),
+ self.assertEqual(sorted(self.repo['default'].manifest().keys()),
['alpha', 'beta'])
@test_util.requiresreplay
@@ -200,6 +212,22 @@ class MapTests(test_util.TestBase):
self.assert_('good-name' in branches)
self.assertEquals(self.repo[2].branch(), 'default')
+ def test_branchmap_regex_and_glob(self):
+ repo_path = self.load_svndump('branchmap.svndump')
+ branchmap = open(self.branchmap, 'w')
+ branchmap.write("syntax:re\n")
+ branchmap.write("bad(.*) = good-\\1 # stuffy\n")
+ branchmap.write("glob:feat* = default\n")
+ branchmap.close()
+ ui = self.ui()
+ ui.setconfig('hgsubversion', 'branchmap', self.branchmap)
+ commands.clone(ui, test_util.fileurl(repo_path),
+ self.wc_path, branchmap=self.branchmap)
+ branches = set(self.repo[i].branch() for i in self.repo)
+ self.assert_('badname' not in branches)
+ self.assert_('good-name' in branches)
+ self.assertEquals(self.repo[2].branch(), 'default')
+
def test_branchmap_tagging(self):
'''test tagging a renamed branch, which used to raise an exception'''
repo_path = self.load_svndump('commit-to-tag.svndump')
@@ -290,6 +318,23 @@ class MapTests(test_util.TestBase):
for r in repo:
self.assertEquals(verify.verify(ui, repo, rev=r), 0)
+ def test_branchmap_no_replacement(self):
+ '''test that empty mappings are accepted
+
+ Empty mappings are lines like 'this ='. We check that such branches are
+ not converted.
+ '''
+ repo_path = self.load_svndump('branchmap.svndump')
+ branchmap = open(self.branchmap, 'w')
+ branchmap.write("badname =\n")
+ branchmap.close()
+ ui = self.ui()
+ ui.setconfig('hgsubversion', 'branchmap', self.branchmap)
+ commands.clone(ui, test_util.fileurl(repo_path),
+ self.wc_path, branchmap=self.branchmap)
+ branches = set(self.repo[i].branch() for i in self.repo)
+ self.assertEquals(sorted(branches), ['default', 'feature'])
+
def test_tagmap(self):
repo_path = self.load_svndump('basic_tag_tests.svndump')
tagmap = open(self.tagmap, 'w')
diff --git a/tests/test_fetch_renames.py b/tests/test_fetch_renames.py
index fad681d..caeeeea 100644
--- a/tests/test_fetch_renames.py
+++ b/tests/test_fetch_renames.py
@@ -34,12 +34,16 @@ class TestFetchRenames(test_util.TestBase):
repo = self._load_fixture_and_fetch('renames_with_prefix.svndump',
subdir='prefix',
config=config)
- self._run_assertions(repo)
+ self._run_assertions(repo, prefix=True)
- def _run_assertions(self, repo):
+ def _run_assertions(self, repo, prefix=False):
# Map revnum to mappings of dest name to (source name, dest content)
+ if prefix:
+ prefixlen = len('svn:ae30a990-0fd3-493e-b5d7-883bdd606745/prefix')
+ else:
+ prefixlen = len('svn:ae30a990-0fd3-493e-b5d7-883bdd606745')
copies = {
- 4: {
+ '/trunk@6': {
'a1': ('a', 'a\n'),
'linka1': ('linka', 'a'),
'a2': ('a', 'a\n'),
@@ -55,32 +59,35 @@ class TestFetchRenames(test_util.TestBase):
'da2/db/dbf': ('da/db/dbf', 'd\n'),
'da2/db/dblink': ('da/db/dblink', '../daf'),
},
- 5: {
+ '/branches/branch1@6': {
'c1': ('c', 'c\nc\n'),
'linkc1': ('linkc', 'cc'),
},
- 9: {
+ '/trunk@10': {
'unchanged2': ('unchanged', 'unchanged\n'),
'unchangedlink2': ('unchangedlink', 'unchanged'),
'unchangeddir2/f': ('unchangeddir/f', 'unchanged2\n'),
'unchangeddir2/link': ('unchangeddir/link', 'f'),
},
- 10: {
+ '/trunk@11': {
'groupdir2/b': ('groupdir/b', 'b\n'),
'groupdir2/linkb': ('groupdir/linkb', 'b'),
},
}
for rev in repo:
ctx = repo[rev]
- copymap = copies.get(rev, {})
+ copymap = copies.get(ctx.extra()['convert_revision'][prefixlen:],
+ {})
for f in ctx.manifest():
cp = ctx[f].renamed()
- self.assertEqual(bool(cp), bool(copymap.get(f)),
- 'copy records differ for %s in %d' % (f, rev))
- if not cp:
- continue
- self.assertEqual(cp[0], copymap[f][0])
- self.assertEqual(ctx[f].data(), copymap[f][1])
+ want = copymap.get(f)
+ self.assertEqual(
+ bool(cp), bool(want),
+ 'copy records differ for %s in %d (want %r, got %r)' % (
+ f, rev, want, cp))
+ if cp:
+ self.assertEqual(cp[0], want[0])
+ self.assertEqual(ctx[f].data(), want[1])
self.assertEqual(repo['tip']['changed3'].data(), 'changed\nchanged3\n')
diff --git a/tests/test_helpers.py b/tests/test_helpers.py
index 219db36..527faea 100644
--- a/tests/test_helpers.py
+++ b/tests/test_helpers.py
@@ -30,3 +30,4 @@ class TestHelpers(unittest.TestCase):
fs.popfile('bb')
self.assertEqual([], os.listdir(fs._tempdir))
self.assertRaises(editor.EditingError, lambda: fs.getfile('bb'))
+ fs.close()
diff --git a/tests/test_hooks.py b/tests/test_hooks.py
index ffd3edc..66197df 100644
--- a/tests/test_hooks.py
+++ b/tests/test_hooks.py
@@ -17,7 +17,7 @@ class TestHooks(test_util.TestBase):
def test_updatemetahook(self):
repo, repo_path = self._loadupdate('single_rev.svndump')
- state = repo.parents()
+ state = repo[None].parents()
self.add_svn_rev(repo_path, {'trunk/alpha': 'Changed'})
commands.pull(self.repo.ui, self.repo)
diff --git a/tests/test_pull.py b/tests/test_pull.py
index 3a1a217..d038094 100644
--- a/tests/test_pull.py
+++ b/tests/test_pull.py
@@ -20,37 +20,37 @@ class TestPull(test_util.TestBase):
def test_nochanges(self):
self._loadupdate('single_rev.svndump')
- state = self.repo.parents()
+ state = self.repo[None].parents()
commands.pull(self.repo.ui, self.repo)
- self.assertEqual(state, self.repo.parents())
+ self.assertEqual(state, self.repo[None].parents())
def test_onerevision_noupdate(self):
repo, repo_path = self._loadupdate('single_rev.svndump')
- state = repo.parents()
+ state = repo[None].parents()
self.add_svn_rev(repo_path, {'trunk/alpha': 'Changed'})
commands.pull(self.repo.ui, repo)
- self.assertEqual(state, repo.parents())
+ self.assertEqual(state, repo[None].parents())
self.assertTrue('tip' not in repo['.'].tags())
def test_onerevision_doupdate(self):
repo, repo_path = self._loadupdate('single_rev.svndump')
- state = repo.parents()
+ state = repo[None].parents()
self.add_svn_rev(repo_path, {'trunk/alpha': 'Changed'})
commands.pull(self.repo.ui, repo, update=True)
- self.failIfEqual(state, repo.parents())
+ self.failIfEqual(state, repo[None].parents())
self.assertTrue('tip' in repo['.'].tags())
def test_onerevision_divergent(self):
repo, repo_path = self._loadupdate('single_rev.svndump')
self.commitchanges((('alpha', 'alpha', 'Changed another way'),))
- state = repo.parents()
+ state = repo[None].parents()
self.add_svn_rev(repo_path, {'trunk/alpha': 'Changed one way'})
try:
commands.pull(self.repo.ui, repo, update=True)
except hgutil.Abort:
# hg < 1.9 raised when crossing branches
pass
- self.assertEqual(state, repo.parents())
+ self.assertEqual(state, repo[None].parents())
self.assertTrue('tip' not in repo['.'].tags())
self.assertEqual(len(repo.heads()), 2)
diff --git a/tests/test_pull_fallback.py b/tests/test_pull_fallback.py
index a2979ff..5d94b16 100644
--- a/tests/test_pull_fallback.py
+++ b/tests/test_pull_fallback.py
@@ -37,14 +37,14 @@ class TestPullFallback(test_util.TestBase):
# Passing stupid=True doesn't seem to be working - force it
repo.ui.setconfig('hgsubversion', 'stupid', "true")
- state = repo.parents()
+ state = repo[None].parents()
calls, replaced = _monkey_patch(to_patch)
try:
self.add_svn_rev(repo_path, {'trunk/alpha': 'Changed'})
commands.pull(self.repo.ui, repo, update=True)
- self.failIfEqual(state, repo.parents())
+ self.failIfEqual(state, repo[None].parents())
self.assertTrue('tip' in repo[None].tags())
self.assertEqual(expected_calls, calls)
diff --git a/tests/test_push_command.py b/tests/test_push_command.py
index a62f3ce..6debbb2 100644
--- a/tests/test_push_command.py
+++ b/tests/test_push_command.py
@@ -138,7 +138,33 @@ class PushTests(test_util.TestBase):
open(os.path.join(repo_path, 'conf', 'svnserve.conf'),
'w').write('[general]\nanon-access=write\n[sasl]\n')
self.port = random.randint(socket.IPPORT_USERRESERVED, 65535)
- self.host = 'localhost'
+ self.host = socket.gethostname()
+
+ # The `svnserve` binary appears to use the obsolete `gethostbyname(3)`
+ # function, which always returns an IPv4 address, even on hosts that
+ # support and expect IPv6. As a workaround, resolve the hostname
+ # within the test harness with `getaddrinfo(3)` to ensure that the
+ # client and server both use the same IPv4 or IPv6 address.
+ addrinfo = socket.getaddrinfo(self.host, self.port)
+ # On macOS svn seems to have issues with IPv6 at least some of
+ # the time, so try and bias towards IPv4. This works because
+ # AF_INET is less than AF_INET6 on all platforms I've
+ # checked. Hopefully any platform where that's not true will
+ # be fine with IPv6 all the time. :)
+ selected = sorted(addrinfo)[0]
+ self.host = selected[4][0]
+
+ # If we're connecting via IPv6 the need to put brackets around the
+ # hostname in the URL.
+ ipv6 = selected[0] == socket.AF_INET6
+
+ # Ditch any interface information since that's not helpful in
+ # a URL
+ if ipv6 and ':' in self.host and '%' in self.host:
+ self.host = self.host.rsplit('%', 1)[0]
+
+ urlfmt = 'svn://[%s]:%d/%s' if ipv6 else 'svn://%s:%d/%s'
+
args = ['svnserve', '--daemon', '--foreground',
'--listen-port=%d' % self.port,
'--listen-host=%s' % self.host,
@@ -152,7 +178,7 @@ class PushTests(test_util.TestBase):
import shutil
shutil.rmtree(self.wc_path)
commands.clone(self.ui(),
- 'svn://%s:%d/%s' % (self.host, self.port, subdir),
+ urlfmt % (self.host, self.port, subdir),
self.wc_path, noupdate=True)
repo = self.repo
diff --git a/tests/test_revmap_migrate.py b/tests/test_revmap_migrate.py
new file mode 100644
index 0000000..4d92b22
--- /dev/null
+++ b/tests/test_revmap_migrate.py
@@ -0,0 +1,72 @@
+import test_util
+
+from mercurial import util as hgutil
+from hgsubversion import svnmeta, maps
+from mercurial.node import hex
+
+class TestRevMapMigrate(test_util.TestBase):
+
+ def tearDown(self):
+ # revert changes to defaultrevmapclass
+ svnmeta.SVNMeta._defaultrevmapclass = maps.RevMap
+
+ def _test_revmap_migrate(self, fromclass, toclass):
+ # revmap interfaces to test
+ getters = [
+ lambda x: x.branchedits('the_branch', 3),
+ lambda x: x.branchedits('the_branch', 4),
+ lambda x: x.branchedits('the_branch', 5),
+ lambda x: x.branchedits('the_branch', 6),
+ lambda x: x.branchedits(None, 5),
+ lambda x: x.branchedits('non_existed', 10),
+ lambda x: x.branchmaxrevnum('the_branch', 3),
+ lambda x: x.branchmaxrevnum('the_branch', 4),
+ lambda x: x.branchmaxrevnum('the_branch', 5),
+ lambda x: x.branchmaxrevnum('the_branch', 6),
+ lambda x: x.branchmaxrevnum(None, 5),
+ lambda x: x.branchmaxrevnum('non_existed', 10),
+ lambda x: list(x.revhashes(3)),
+ lambda x: list(x.revhashes(4)),
+ lambda x: list(x.revhashes(42)),
+ lambda x: list(x.revhashes(105)),
+ lambda x: x.firstpulled,
+ lambda x: x.lastpulled,
+ lambda x: x.lasthash,
+ ]
+
+ svnmeta.SVNMeta._defaultrevmapclass = fromclass
+ repo = self._load_fixture_and_fetch('two_heads.svndump')
+ meta = svnmeta.SVNMeta(repo)
+ self.assertEqual(meta.revmap.__class__, fromclass)
+ origrevmap = meta.revmap
+
+ # insert fake special (duplicated, with '\0') data
+ origrevmap[103, None] = b'\0' * 20
+ origrevmap[104, None] = b'\0' * 18 + b'cd'
+ origrevmap[105, None] = b'ab\0cdefghijklmnopqrs'
+ origrevmap[104, None] = b'\0' * 18 + b'\xff\0'
+ origrevmap[105, 'ab'] = origrevmap[105, None]
+
+ origvalues = [f(meta.revmap) for f in getters]
+
+ # migrate to another format (transparently)
+ svnmeta.SVNMeta._defaultrevmapclass = toclass
+ meta = svnmeta.SVNMeta(repo)
+ self.assertEqual(meta.revmap.__class__, toclass)
+
+ # enable iteration otherwise we cannot use iteritems
+ origrevmap._allowiter = True
+ for k, v in origrevmap.iteritems():
+ newv = meta.revmap[k]
+ self.assertEqual(newv, v)
+ self.assertEqual(len(newv), 20)
+ self.assertEqual(meta.revmap[meta.revmap.hashes()[v]], v)
+
+ newvalues = [f(meta.revmap) for f in getters]
+ self.assertEqual(origvalues, newvalues)
+
+ def test_revmap_migrate_up(self):
+ self._test_revmap_migrate(maps.RevMap, maps.SqliteRevMap)
+
+ def test_revmap_migrate_down(self):
+ self._test_revmap_migrate(maps.SqliteRevMap, maps.RevMap)
diff --git a/tests/test_svnwrap.py b/tests/test_svnwrap.py
index d71c9e4..4db069f 100644
--- a/tests/test_svnwrap.py
+++ b/tests/test_svnwrap.py
@@ -11,15 +11,11 @@ class TestBasicRepoLayout(unittest.TestCase):
def setUp(self):
self.tmpdir = tempfile.mkdtemp('svnwrap_test')
self.repo_path = '%s/testrepo' % self.tmpdir
- subprocess.call(['svnadmin', 'create', self.repo_path, ])
- inp = open(os.path.join(os.path.dirname(__file__), 'fixtures',
- 'project_root_at_repo_root.svndump'))
- proc = subprocess.call(['svnadmin', 'load', self.repo_path, ],
- stdin=inp,
- close_fds=test_util.canCloseFds,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- assert proc == 0
+
+ with open(os.path.join(test_util.FIXTURES,
+ 'project_root_at_repo_root.svndump')) as fp:
+ svnwrap.create_and_load(self.repo_path, fp)
+
self.repo = svnwrap.SubversionRepo(test_util.fileurl(self.repo_path))
def tearDown(self):
diff --git a/tests/test_tags.py b/tests/test_tags.py
index cfd2659..2a0f06b 100644
--- a/tests/test_tags.py
+++ b/tests/test_tags.py
@@ -4,6 +4,7 @@ import os, sys, cStringIO, difflib
import unittest
from mercurial import commands
+from mercurial import error
from mercurial import hg
from mercurial import node
from mercurial import ui
@@ -128,10 +129,8 @@ rename a tag
'branch': 'magic',
'convert_revision': 'svn:af82cc90-c2d2-43cd-b1aa-c8a78449440a/tags/will-edit@19'})
self.assertEqual(willedit, repo.tags()['will-edit'])
- self.assertEqual(repo['will-edit'].manifest().keys(), ['alpha',
- 'beta',
- 'gamma',
- ])
+ self.assertEqual(sorted(repo['will-edit'].manifest().keys()),
+ ['alpha', 'beta', 'gamma'])
self.assertEqual(
repo[alsoedit].extra(),
{'close': '1',
@@ -164,14 +163,12 @@ rename a tag
'magic2': '\xa3\xa2D\x86aM\xc0v\xb9\xb0\x18\x14\xad\xacwBUi}\xe2',
})
- def test_old_tag_map_rebuilds(self):
+ def test_old_tag_map_aborts(self):
repo = self._load_fixture_and_fetch('tag_name_same_as_branch.svndump')
tm = os.path.join(repo.path, 'svn', 'tagmap')
open(tm, 'w').write('1\n')
# force tags to load since it is lazily loaded when needed
- repo.svnmeta().tags
- commands.pull(repo.ui, repo)
- self.assertEqual(open(tm).read().splitlines()[0], '2')
+ self.assertRaises(error.Abort, lambda: repo.svnmeta().tags)
def _debug_print_tags(self, repo, ctx, fp):
def formatnode(ctx):
diff --git a/tests/test_urls.py b/tests/test_urls.py
index 591ac22..a790f16 100644
--- a/tests/test_urls.py
+++ b/tests/test_urls.py
@@ -8,58 +8,61 @@ from hgsubversion import svnrepo
class TestSubversionUrls(test_util.TestBase):
def test_standard_url(self):
- self.assertEqual((None, None, 'file:///var/svn/repo'),
- parse_url('file:///var/svn/repo'))
+ self.check_parse_url((None, None, 'file:///var/svn/repo'),
+ ('file:///var/svn/repo', ))
def test_user_url(self):
- self.assertEqual(
+ self.check_parse_url(
('joe', None, 'https://svn.testurl.com/repo'),
- parse_url('https://joe@svn.testurl.com/repo'))
- self.assertEqual(
+ ('https://joe@svn.testurl.com/repo', ))
+ self.check_parse_url(
('bob', None, 'https://svn.testurl.com/repo'),
- parse_url('https://joe@svn.testurl.com/repo', 'bob'))
+ ('https://joe@svn.testurl.com/repo', 'bob', ))
def test_password_url(self):
- self.assertEqual(
+ self.check_parse_url(
(None, 't3stpw', 'svn+ssh://svn.testurl.com/repo'),
- parse_url('svn+ssh://:t3stpw@svn.testurl.com/repo'))
- self.assertEqual(
+ ('svn+ssh://:t3stpw@svn.testurl.com/repo', ))
+ self.check_parse_url(
(None, '123abc', 'svn+ssh://svn.testurl.com/repo'),
- parse_url('svn+ssh://:t3stpw@svn.testurl.com/repo', None, '123abc'))
+ ('svn+ssh://:t3stpw@svn.testurl.com/repo', None, '123abc', ))
def test_svnssh_preserve_user(self):
- self.assertEqual(
+ self.check_parse_url(
('user', 't3stpw', 'svn+ssh://user@svn.testurl.com/repo',),
- parse_url('svn+ssh://user:t3stpw@svn.testurl.com/repo'))
- self.assertEqual(
+ ('svn+ssh://user:t3stpw@svn.testurl.com/repo', ))
+ self.check_parse_url(
('bob', '123abc', 'svn+ssh://bob@svn.testurl.com/repo',),
- parse_url('svn+ssh://user:t3stpw@svn.testurl.com/repo', 'bob', '123abc'))
- self.assertEqual(
+ ('svn+ssh://user:t3stpw@svn.testurl.com/repo', 'bob', '123abc', ))
+ self.check_parse_url(
('user2', None, 'svn+ssh://user2@svn.testurl.com/repo',),
- parse_url('svn+ssh://user2@svn.testurl.com/repo'))
- self.assertEqual(
+ ('svn+ssh://user2@svn.testurl.com/repo', ))
+ self.check_parse_url(
('bob', None, 'svn+ssh://bob@svn.testurl.com/repo',),
- parse_url('svn+ssh://user2@svn.testurl.com/repo', 'bob'))
+ ('svn+ssh://user2@svn.testurl.com/repo', 'bob', ))
def test_user_password_url(self):
- self.assertEqual(
+ self.check_parse_url(
('joe', 't3stpw', 'https://svn.testurl.com/repo'),
- parse_url('https://joe:t3stpw@svn.testurl.com/repo'))
- self.assertEqual(
+ ('https://joe:t3stpw@svn.testurl.com/repo', ))
+ self.check_parse_url(
('bob', '123abc', 'https://svn.testurl.com/repo'),
- parse_url('https://joe:t3stpw@svn.testurl.com/repo', 'bob', '123abc'))
+ ('https://joe:t3stpw@svn.testurl.com/repo', 'bob', '123abc', ))
def test_url_rewriting(self):
ui = test_util.ui.ui()
ui.setconfig('hgsubversion', 'username', 'bob')
repo = svnrepo.svnremoterepo(ui, 'svn+ssh://joe@foo/bar')
self.assertEqual('svn+ssh://bob@foo/bar', repo.svnauth[0])
+ self.assertEqual('svn+ssh://bob@foo/bar', repo.svnurl)
repo = svnrepo.svnremoterepo(ui, 'svn+http://joe@foo/bar')
self.assertEqual(('http://foo/bar', 'bob', None), repo.svnauth)
+ self.assertEqual('http://foo/bar', repo.svnurl)
repo = svnrepo.svnremoterepo(ui, 'svn+https://joe@foo/bar')
self.assertEqual(('https://foo/bar', 'bob', None), repo.svnauth)
+ self.assertEqual('https://foo/bar', repo.svnurl)
def test_quoting(self):
ui = self.ui()
@@ -72,3 +75,11 @@ class TestSubversionUrls(test_util.TestBase):
repo1 = svnrepo.svnremoterepo(ui, repo_url + subdir)
repo2 = svnrepo.svnremoterepo(ui, repo_url + quoted_subdir)
self.assertEqual(repo1.svnurl, repo2.svnurl)
+
+ def check_parse_url(self, expected, args):
+ self.assertEqual(expected, parse_url(*args))
+ if len(args) == 1:
+ repo = svnrepo.svnremoterepo(self.ui(), path=args[0])
+ self.assertEqual(expected[2], repo.svnauth[0])
+ self.assertEqual(expected[2], repo.svnurl)
+
diff --git a/tests/test_util.py b/tests/test_util.py
index b24c35a..7c78c51 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -28,6 +28,7 @@ from mercurial import util as hgutil
from mercurial import extensions
from hgsubversion import compathacks
+from hgsubversion import svnrepo
from hgsubversion import svnwrap
try:
@@ -39,14 +40,12 @@ except ImportError:
try:
SkipTest = unittest.SkipTest
except AttributeError:
- try:
- from unittest2 import SkipTest
- except ImportError:
- try:
- from nose import SkipTest
- except ImportError:
- SkipTest = None
+ if 'nose' in sys.modules:
+ SkipTest = sys.modules['nose'].SkipTest
+ else:
+ SkipTest = None
+from hgsubversion import svnwrap
from hgsubversion import util
from hgsubversion import svnwrap
@@ -210,15 +209,25 @@ def getlocalpeer(repo):
localrepo = repo
return localrepo
-def repolen(repo):
+def repolen(repo, svnonly=False):
"""Naively calculate the amount of available revisions in a repository.
this is usually equal to len(repo) -- except in the face of
obsolete revisions.
+
+ if svnonly is true, only count revisions converted from Subversion.
"""
# kind of nasty way of calculating the length, but fortunately,
# our test repositories tend to be rather small
- return len([r for r in repo])
+ revs = set(repo)
+
+ if obsolete:
+ revs -= obsolete.getrevs(repo, 'obsolete')
+
+ if svnonly:
+ revs = set(r for r in revs if util.getsvnrev(repo[r]))
+
+ return len(revs)
def _makeskip(name, message):
if SkipTest:
@@ -284,10 +293,12 @@ def testui(stupid=False, layout='auto', startrev=0):
u = ui.ui()
bools = {True: 'true', False: 'false'}
u.setconfig('ui', 'quiet', bools[True])
+ u.setconfig('ui', 'username', 'automated tests')
u.setconfig('extensions', 'hgsubversion', '')
u.setconfig('hgsubversion', 'stupid', bools[stupid])
u.setconfig('hgsubversion', 'layout', layout)
u.setconfig('hgsubversion', 'startrev', startrev)
+ u.setconfig('devel', 'all-warnings', True)
return u
def dispatch(cmd):
@@ -534,12 +545,8 @@ class TestBase(unittest.TestCase):
'''
path = self._makerepopath()
assert not os.path.exists(path)
- subprocess.call(['svnadmin', 'create', path,],
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- inp = open(os.path.join(FIXTURES, fixture_name))
- proc = subprocess.Popen(['svnadmin', 'load', path,], stdin=inp,
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- proc.communicate()
+ with open(os.path.join(FIXTURES, fixture_name)) as inp:
+ svnwrap.create_and_load(path, inp)
return path
def load_repo_tarball(self, fixture_name):
@@ -596,7 +603,7 @@ class TestBase(unittest.TestCase):
return hg.repository(testui(), self.wc_path)
- def load_and_fetch(self, fixture_name, *args, **opts):
+ def load(self, fixture_name):
if fixture_name.endswith('.svndump'):
repo_path = self.load_svndump(fixture_name)
elif fixture_name.endswith('tar.gz'):
@@ -604,6 +611,10 @@ class TestBase(unittest.TestCase):
else:
assert False, 'Unknown fixture type'
+ return repo_path
+
+ def load_and_fetch(self, fixture_name, *args, **opts):
+ repo_path = self.load(fixture_name)
return self.fetch(repo_path, *args, **opts), repo_path
def _load_fixture_and_fetch(self, *args, **kwargs):
@@ -704,7 +715,8 @@ class TestBase(unittest.TestCase):
changed + removed,
filectxfn,
'an_author',
- '2008-10-07 20:59:48 -0500')
+ '2008-10-07 20:59:48 -0500',
+ {'branch': parentctx.branch()})
nodeid = repo.commitctx(ctx)
repo = self.repo
hg.clean(repo, nodeid)
@@ -773,5 +785,21 @@ files: {files}
commands.log(_ui, repo, rev=None, template=templ, graph=True)
return _ui.popbuffer()
+ def svnlog(self, repo=None):
+ '''log of the remote Subversion repository corresponding to repo
+
+ In order to make the format suitable for direct comparison in
+ tests, we exclude dates and convert the path operations into
+ a tuple.
+ '''
+
+ if repo is None:
+ repo = self.repo
+
+ return [(r.revnum, r.message,
+ dict((p, (op.action, op.copyfrom_path, int(op.copyfrom_rev)))
+ for (p, op) in r.paths.items()))
+ for r in svnrepo.svnremoterepo(repo.ui).svn.revisions()]
+
def draw(self, repo):
sys.stdout.write(self.getgraph(repo))
diff --git a/tests/test_utility_commands.py b/tests/test_utility_commands.py
index 5b03901..481c64b 100644
--- a/tests/test_utility_commands.py
+++ b/tests/test_utility_commands.py
@@ -128,10 +128,10 @@ class UtilityTests(test_util.TestBase):
def test_missing_metadata(self):
self._load_fixture_and_fetch('two_heads.svndump')
- os.remove(self.repo.join('svn/branch_info'))
+ os.remove(self.repo.vfs.join('svn/branch_info'))
svncommands.updatemeta(self.ui(), self.repo, [])
- test_util.rmtree(self.repo.join('svn'))
+ test_util.rmtree(self.repo.vfs.join('svn'))
self.assertRaises(hgutil.Abort,
self.repo.svnmeta)
self.assertRaises(hgutil.Abort,
@@ -141,7 +141,7 @@ class UtilityTests(test_util.TestBase):
svncommands.genignore,
self.ui(), repo=self.repo, args=[])
- os.remove(self.repo.join('hgrc'))
+ os.remove(self.repo.vfs.join('hgrc'))
self.assertRaises(hgutil.Abort,
self.repo.svnmeta)
self.assertRaises(hgutil.Abort,