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