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__)