Mercurial > hg
comparison tests/test-atomictempfile.py @ 29201:a109bf7e0dc2
util: make atomictempfile avoid ambiguity of file stat if needed
Ambiguity check is executed at close(), only if:
- atomictempfile is created with checkambig=True, and
- target file exists before renaming
This restriction avoids performance decrement by needless examination
of file stat (for example, filelog doesn't need exact cache
validation, even though it uses atomictempfile to write changes out).
See description of filestat class for detail about why the logic in
this patch works as expected.
This patch is a part of preparation for "Exact Cache Validation Plan":
https://www.mercurial-scm.org/wiki/ExactCacheValidationPlan
author | FUJIWARA Katsunori <foozy@lares.dti.ne.jp> |
---|---|
date | Thu, 19 May 2016 00:20:38 +0900 |
parents | 3bea82dd4c4e |
children | 1acf654f0985 |
comparison
equal
deleted
inserted
replaced
29200:ca4065028e00 | 29201:a109bf7e0dc2 |
---|---|
40 # if a programmer screws up and passes bad args to atomictempfile, they | 40 # if a programmer screws up and passes bad args to atomictempfile, they |
41 # get a plain ordinary TypeError, not infinite recursion | 41 # get a plain ordinary TypeError, not infinite recursion |
42 def test3_oops(self): | 42 def test3_oops(self): |
43 self.assertRaises(TypeError, atomictempfile) | 43 self.assertRaises(TypeError, atomictempfile) |
44 | 44 |
45 # checkambig=True avoids ambiguity of timestamp | |
46 def test4_checkambig(self): | |
47 def atomicwrite(checkambig): | |
48 f = atomictempfile('foo', checkambig=checkambig) | |
49 f.write('FOO') | |
50 f.close() | |
51 | |
52 # try some times, because reproduction of ambiguity depends on | |
53 # "filesystem time" | |
54 for i in xrange(5): | |
55 atomicwrite(False) | |
56 oldstat = os.stat('foo') | |
57 if oldstat.st_ctime != oldstat.st_mtime: | |
58 # subsequent changing never causes ambiguity | |
59 continue | |
60 | |
61 repetition = 3 | |
62 | |
63 # repeat atomic write with checkambig=True, to examine | |
64 # whether st_mtime is advanced multiple times as expecetd | |
65 for j in xrange(repetition): | |
66 atomicwrite(True) | |
67 newstat = os.stat('foo') | |
68 if oldstat.st_ctime != newstat.st_ctime: | |
69 # timestamp ambiguity was naturally avoided while repetition | |
70 continue | |
71 | |
72 # st_mtime should be advanced "repetition" times, because | |
73 # all atomicwrite() occured at same time (in sec) | |
74 self.assertTrue(newstat.st_mtime == | |
75 ((oldstat.st_mtime + repetition) & 0x7fffffff)) | |
76 # no more examination is needed, if assumption above is true | |
77 break | |
78 else: | |
79 # This platform seems too slow to examine anti-ambiguity | |
80 # of file timestamp (or test happened to be executed at | |
81 # bad timing). Exit silently in this case, because running | |
82 # on other faster platforms can detect problems | |
83 pass | |
84 | |
45 if __name__ == '__main__': | 85 if __name__ == '__main__': |
46 import silenttestrunner | 86 import silenttestrunner |
47 silenttestrunner.main(__name__) | 87 silenttestrunner.main(__name__) |