annotate tests/test_svnwrap.py @ 1233:0d0132cba155

editor: fix edge case with in memory file-store size limit There are a few cases where we will set a single file into to the editor's FileStore object more than once. Notably, for copied and then modified files, we will set it at least twice. Three times if editing fails (which it can for symlinks). If we pass the in-memory storage limit in between the first (or second if editing fails) time we set the file and the last time we set the file, we will write the data to the in memory store the first time and the file store the last time. We didn't remove it form the in-memory store though, and we always prefer reading from the in-memory store. This means we can sometimes end up with the wrong version of a file. This is fairly unlikely to happen in normal use since you need to hit the memory limit between two writes to the store for the same file. We only write a file multiple times if a) the file (and not one of it's parent directories) is copied and then modified or b) editing fails. From what I can tell, it's only common for editing to fail for symlinks, and they ten to be relatively small data that is unlikely to push over the limit. Finally, the default limit is 100MB which I would expect to be most often either well over (source code) or well under (binaries or automated changes) the size of the changes files in a single commit. The easiest way to reproduce this is to set the in-memory cache size to 0 and then commit a copied and modified symlink. The empty-string version from the failed editing will be the one that persists. I happened to stumble upon this while trying (and failing) to test a bug-fix for a related bug with identical symptoms (empty simlink). I have seen this in the wild, once, but couldn't reproduce it at the time. The repo in question is quite large and quite active, so I am quite confident in my estimation that this is a real, but very rare, problem. The test changes attached to this was mneant to test a related bug, but turned out not to actually cover the bug in question. They did trigger this bug though, and are worthwhile to test, so I kept them.
author David Schleimer <dschleimer@fb.com>
date Mon, 07 Apr 2014 17:51:59 -0700
parents d741f536f23a
children 019c3e194fba
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
643
d2ef7220a079 tests: import test_util as the first module in all relevant tests
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 642
diff changeset
1 import test_util
d2ef7220a079 tests: import test_util as the first module in all relevant tests
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 642
diff changeset
2
347
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
3 import os
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
4 import subprocess
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
5 import tempfile
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
6 import unittest
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
7
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
8 from hgsubversion import svnwrap
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
9
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
10 class TestBasicRepoLayout(unittest.TestCase):
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
11 def setUp(self):
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
12 self.tmpdir = tempfile.mkdtemp('svnwrap_test')
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
13 self.repo_path = '%s/testrepo' % self.tmpdir
832
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 666
diff changeset
14 subprocess.call(['svnadmin', 'create', self.repo_path, ])
347
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
15 inp = open(os.path.join(os.path.dirname(__file__), 'fixtures',
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
16 'project_root_at_repo_root.svndump'))
832
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 666
diff changeset
17 proc = subprocess.call(['svnadmin', 'load', self.repo_path, ],
479
83fcb1cf6d8f Avoid 'ValueError: close_fds is not supported on Windows platforms' exception
Risto Kankkunen <risto.kankkunen@iki.fi>
parents: 478
diff changeset
18 stdin=inp,
83fcb1cf6d8f Avoid 'ValueError: close_fds is not supported on Windows platforms' exception
Risto Kankkunen <risto.kankkunen@iki.fi>
parents: 478
diff changeset
19 close_fds=test_util.canCloseFds,
347
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
20 stdout=subprocess.PIPE,
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
21 stderr=subprocess.STDOUT)
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
22 assert proc == 0
480
7fa100ae1a11 Avoid 'Abort: Illegal repository URL' exception
Risto Kankkunen <risto.kankkunen@iki.fi>
parents: 479
diff changeset
23 self.repo = svnwrap.SubversionRepo(test_util.fileurl(self.repo_path))
347
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
24
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
25 def tearDown(self):
482
a42fb4f1716a Reclaim repository object to avoid tearDown() failing to remove the open file 'testrepo/db/rep-cache.db'
Risto Kankkunen <risto.kankkunen@iki.fi>
parents: 481
diff changeset
26 del self.repo
873
c58213aaf7c8 test_svnwrap: use test_util.rmtree() (or fix it)
Patrick Mezard <patrick@mezard.eu>
parents: 833
diff changeset
27 test_util.rmtree(self.tmpdir)
347
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
28
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
29 def test_num_revs(self):
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
30 revs = list(self.repo.revisions())
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
31 self.assertEqual(len(revs), 7)
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
32 r = revs[1]
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
33 self.assertEqual(r.revnum, 2)
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
34 self.assertEqual(sorted(r.paths.keys()),
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
35 ['trunk/alpha', 'trunk/beta', 'trunk/delta'])
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
36 for r in revs:
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
37 for p in r.paths:
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
38 # make sure these paths are always non-absolute for sanity
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
39 if p:
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
40 assert p[0] != '/'
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
41 revs = list(self.repo.revisions(start=3))
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
42 self.assertEqual(len(revs), 4)
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
43
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
44 class TestRootAsSubdirOfRepo(TestBasicRepoLayout):
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
45 def setUp(self):
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
46 self.tmpdir = tempfile.mkdtemp('svnwrap_test')
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
47 self.repo_path = '%s/testrepo' % self.tmpdir
832
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 666
diff changeset
48 subprocess.call(['svnadmin', 'create', self.repo_path, ])
347
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
49 inp = open(os.path.join(os.path.dirname(__file__), 'fixtures',
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
50 'project_root_not_repo_root.svndump'))
832
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 666
diff changeset
51 ret = subprocess.call(['svnadmin', 'load', self.repo_path, ],
479
83fcb1cf6d8f Avoid 'ValueError: close_fds is not supported on Windows platforms' exception
Risto Kankkunen <risto.kankkunen@iki.fi>
parents: 478
diff changeset
52 stdin=inp,
83fcb1cf6d8f Avoid 'ValueError: close_fds is not supported on Windows platforms' exception
Risto Kankkunen <risto.kankkunen@iki.fi>
parents: 478
diff changeset
53 close_fds=test_util.canCloseFds,
347
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
54 stdout=subprocess.PIPE,
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
55 stderr=subprocess.STDOUT)
537de0300510 Remove the 'outgoing' wrapper, and use the Mercurial infrastructure instead.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
diff changeset
56 assert ret == 0
480
7fa100ae1a11 Avoid 'Abort: Illegal repository URL' exception
Risto Kankkunen <risto.kankkunen@iki.fi>
parents: 479
diff changeset
57 self.repo = svnwrap.SubversionRepo(test_util.fileurl(
7fa100ae1a11 Avoid 'Abort: Illegal repository URL' exception
Risto Kankkunen <risto.kankkunen@iki.fi>
parents: 479
diff changeset
58 self.repo_path + '/dummyproj'
7fa100ae1a11 Avoid 'Abort: Illegal repository URL' exception
Risto Kankkunen <risto.kankkunen@iki.fi>
parents: 479
diff changeset
59 ))