annotate tests/test_push_renames.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 9a740cbb6895
children a36e87ae2380
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: 512
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: 512
diff changeset
2
70
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
3 import sys
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
4 import unittest
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
5
82
71de43e9f614 Extract PushTest common code into test_util.TestBase
Patrick Mezard <pmezard@gmail.com>
parents: 78
diff changeset
6 class TestPushRenames(test_util.TestBase):
1055
2d7398fffd0d push: obsolete rather than rebase & strip when enabled
Dan Villiom Podlaski Christiansen <dan@cabo.dk>
parents: 1044
diff changeset
7 obsolete_mode_tests = True
1073
9a740cbb6895 test_push_renames: use metaclass stupid mode tests
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 1055
diff changeset
8 stupid_mode_tests = True
1055
2d7398fffd0d push: obsolete rather than rebase & strip when enabled
Dan Villiom Podlaski Christiansen <dan@cabo.dk>
parents: 1044
diff changeset
9
70
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
10 def setUp(self):
82
71de43e9f614 Extract PushTest common code into test_util.TestBase
Patrick Mezard <pmezard@gmail.com>
parents: 78
diff changeset
11 test_util.TestBase.setUp(self)
1073
9a740cbb6895 test_push_renames: use metaclass stupid mode tests
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 1055
diff changeset
12 self.repo_path = self.load_and_fetch('pushrenames.svndump')[1]
70
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
13
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
14 def _debug_print_copies(self, ctx):
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
15 w = sys.stderr.write
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
16 for f in ctx.files():
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
17 if f not in ctx:
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
18 w('R %s\n' % f)
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
19 else:
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
20 w('U %s %r\n' % (f, ctx[f].data()))
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
21 if ctx[f].renamed():
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
22 w('%s copied from %s\n' % (f, ctx[f].renamed()[0]))
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
23
84
01e747937d35 test_util: add commitchanges() to TestBase
Patrick Mezard <pmezard@gmail.com>
parents: 82
diff changeset
24 def test_push_renames(self):
70
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
25 repo = self.repo
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
26
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
27 changes = [
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
28 # Regular copy of a single file
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
29 ('a', 'a2', None),
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
30 # Copy and update of target
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
31 ('a', 'a3', 'aa\n'),
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
32 # Regular move of a single file
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
33 ('b', 'b2', None),
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
34 ('b', None, None),
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
35 # Regular move and update of target
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
36 ('c', 'c2', 'c\nc\n'),
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
37 ('c', None, None),
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
38 # Copy and update of source and targets
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
39 ('d', 'd2', 'd\nd2\n'),
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
40 ('d', 'd', 'd\nd\n'),
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
41 # Double copy and removal (aka copy and move)
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
42 ('e', 'e2', 'e\ne2\n'),
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
43 ('e', 'e3', 'e\ne3\n'),
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
44 ('e', None, None),
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
45 ]
84
01e747937d35 test_util: add commitchanges() to TestBase
Patrick Mezard <pmezard@gmail.com>
parents: 82
diff changeset
46 self.commitchanges(changes)
01e747937d35 test_util: add commitchanges() to TestBase
Patrick Mezard <pmezard@gmail.com>
parents: 82
diff changeset
47 self.pushrevisions()
70
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
48 tip = self.repo['tip']
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
49 # self._debug_print_copies(tip)
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
50 self.assertchanges(changes, tip)
49b7cbe4c8e3 push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
diff changeset
51
512
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
52 def test_push_rename_with_space(self):
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
53 changes = [
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
54 ('random/dir with space/file with space',
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
55 'random/dir with space/file with space',
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
56 'file contents'),
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
57 ]
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
58 self.commitchanges(changes)
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
59
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
60 changes = [
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
61 ('random/dir with space/file with space',
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
62 'random2/dir with space/file with space',
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
63 None),
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
64 ('random/dir with space/file with space',
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
65 None, None),
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
66 ]
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
67 self.commitchanges(changes)
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
68 self.pushrevisions()
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
69 self.assertEqual(self.repo['tip'].manifest().keys(),
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
70 ['a', 'c', 'b', 'e', 'd',
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
71 'random2/dir with space/file with space'])
c421e6bf0d95 tests: test paths with spaces
Augie Fackler <durin42@gmail.com>
parents: 323
diff changeset
72
323
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
73 def test_push_rename_tree(self):
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
74 repo = self.repo
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
75
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
76 changes = [
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
77 ('geek/alpha', 'geek/alpha', 'content',),
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
78 ('geek/beta', 'geek/beta', 'content',),
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
79 ('geek/delta', 'geek/delta', 'content',),
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
80 ('geek/gamma', 'geek/gamma', 'content',),
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
81 ('geek/later/pi', 'geek/later/pi', 'content geek/later/pi',),
832
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
82 ('geek/later/rho', 'geek/later/rho', 'content geek/later/rho',),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
83 ('geek/other/blah', 'geek/other/blah', 'content geek/other/blah',),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
84 ('geek/other/another/layer', 'geek/other/another/layer', 'content deep file',),
323
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
85 ]
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
86
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
87 self.commitchanges(changes)
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
88 self.pushrevisions()
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
89 self.assertchanges(changes, self.repo['tip'])
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
90
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
91 changes = [
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
92 # rename (copy + remove) all of geek to greek
832
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
93 ('geek/alpha', 'greek/alpha', None,),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
94 ('geek/beta', 'greek/beta', None,),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
95 ('geek/delta', 'greek/delta', None,),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
96 ('geek/gamma', 'greek/gamma', None,),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
97 ('geek/later/pi', 'greek/later/pi', None,),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
98 ('geek/later/rho', 'greek/later/rho', None,),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
99 ('geek/other/blah', 'greek/other/blah', None,),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
100 ('geek/other/another/layer', 'greek/other/another/layer', None,),
323
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
101
832
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
102 ('geek/alpha', None, None,),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
103 ('geek/beta', None, None,),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
104 ('geek/delta', None, None,),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
105 ('geek/gamma', None, None,),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
106 ('geek/later/pi', None, None,),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
107 ('geek/later/rho', None, None,),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
108 ('geek/other/blah', None, None,),
e9af7eba88db globally: clean up whitespace around operators and commas to conform with PEP8
Yonggang Luo <luoyonggang@gmail.com>
parents: 643
diff changeset
109 ('geek/other/another/layer', None, None,),
323
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
110 ]
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
111 self.commitchanges(changes)
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
112 self.pushrevisions()
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
113 assert reduce(lambda x, y: x and y,
869
db3a651494f9 test_util: pass repo_path to svnls(), turn it into a function
Patrick Mezard <patrick@mezard.eu>
parents: 865
diff changeset
114 ('geek' not in f for f in test_util.svnls(self.repo_path, 'trunk'))), (
323
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
115 'This failure means rename of an entire tree is broken.'
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
116 ' There is a print on the preceding line commented out '
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 96
diff changeset
117 'that should help you.')