Mercurial > hgsubversion
comparison tests/test_util.py @ 1457:019c3e194fba
tests: optimise creating repositories and loading dumps
Previously, we'd use svnadmin for creating repositories and loading
dumps. That tends to be a bit slow, as it forks a new process and
loads the Subversion libraries into it. Instead, we extend our
existing Subversion wrappers and load the dumps using the API.
This is a noticable speedup. The only downside is that we rely on
Subversion and Subvertpy to correctly close all file descriptors; an
assumption which hasn't always held in the past.
I ran some benchmarks on my relatively slow Mac with $TMPDIR on a
ramdisk, and they showed a significant change:
I compared ten runs of each with Subvertpy:
min: -18.8% (299.1s -> 243.0s)
median: -20.0% (307.1s -> 245.6s)
...and three runs of each with SWIG:
min: -22.8% (368.7s -> 284.7s)
median: -25.7% (384.4s -> 285.5s)
(Since the timing measures wall clock time, the minimum time is likely
to be the most accurate and useful measurement.)
author | Dan Villiom Podlaski Christiansen <danchr@gmail.com> |
---|---|
date | Tue, 07 Jun 2016 09:15:53 +0200 |
parents | 89997a5fc181 |
children | dcf9eff9b5b7 |
comparison
equal
deleted
inserted
replaced
1456:77da55e0baa4 | 1457:019c3e194fba |
---|---|
45 try: | 45 try: |
46 from nose import SkipTest | 46 from nose import SkipTest |
47 except ImportError: | 47 except ImportError: |
48 SkipTest = None | 48 SkipTest = None |
49 | 49 |
50 from hgsubversion import svnwrap | |
50 from hgsubversion import util | 51 from hgsubversion import util |
51 from hgsubversion import svnwrap | 52 from hgsubversion import svnwrap |
52 | 53 |
53 # Documentation for Subprocess.Popen() says: | 54 # Documentation for Subprocess.Popen() says: |
54 # "Note that on Windows, you cannot set close_fds to true and | 55 # "Note that on Windows, you cannot set close_fds to true and |
532 '''Loads an svnadmin dump into a fresh repo. Return the svn repo | 533 '''Loads an svnadmin dump into a fresh repo. Return the svn repo |
533 path. | 534 path. |
534 ''' | 535 ''' |
535 path = self._makerepopath() | 536 path = self._makerepopath() |
536 assert not os.path.exists(path) | 537 assert not os.path.exists(path) |
537 subprocess.call(['svnadmin', 'create', path,], | 538 with open(os.path.join(FIXTURES, fixture_name)) as inp: |
538 stdout=subprocess.PIPE, stderr=subprocess.STDOUT) | 539 svnwrap.create_and_load(path, inp) |
539 inp = open(os.path.join(FIXTURES, fixture_name)) | |
540 proc = subprocess.Popen(['svnadmin', 'load', path,], stdin=inp, | |
541 stdout=subprocess.PIPE, stderr=subprocess.STDOUT) | |
542 proc.communicate() | |
543 return path | 540 return path |
544 | 541 |
545 def load_repo_tarball(self, fixture_name): | 542 def load_repo_tarball(self, fixture_name): |
546 '''Extracts a tarball of an svn repo and returns the svn repo path.''' | 543 '''Extracts a tarball of an svn repo and returns the svn repo path.''' |
547 path = self._makerepopath() | 544 path = self._makerepopath() |
594 r = dispatch(cmd) | 591 r = dispatch(cmd) |
595 assert not r, 'fetch of %s failed' % projectpath | 592 assert not r, 'fetch of %s failed' % projectpath |
596 | 593 |
597 return hg.repository(testui(), self.wc_path) | 594 return hg.repository(testui(), self.wc_path) |
598 | 595 |
599 def load_and_fetch(self, fixture_name, *args, **opts): | 596 def load(self, fixture_name): |
600 if fixture_name.endswith('.svndump'): | 597 if fixture_name.endswith('.svndump'): |
601 repo_path = self.load_svndump(fixture_name) | 598 repo_path = self.load_svndump(fixture_name) |
602 elif fixture_name.endswith('tar.gz'): | 599 elif fixture_name.endswith('tar.gz'): |
603 repo_path = self.load_repo_tarball(fixture_name) | 600 repo_path = self.load_repo_tarball(fixture_name) |
604 else: | 601 else: |
605 assert False, 'Unknown fixture type' | 602 assert False, 'Unknown fixture type' |
606 | 603 |
604 return repo_path | |
605 | |
606 def load_and_fetch(self, fixture_name, *args, **opts): | |
607 repo_path = self.load(fixture_name) | |
607 return self.fetch(repo_path, *args, **opts), repo_path | 608 return self.fetch(repo_path, *args, **opts), repo_path |
608 | 609 |
609 def _load_fixture_and_fetch(self, *args, **kwargs): | 610 def _load_fixture_and_fetch(self, *args, **kwargs): |
610 repo, repo_path = self.load_and_fetch(*args, **kwargs) | 611 repo, repo_path = self.load_and_fetch(*args, **kwargs) |
611 return repo | 612 return repo |