annotate tests/test-atomictempfile.py @ 29391:1acf654f0985

atomictempfile: use a tempdir to keep the test environment clean Rather than pre-emptively delete a file, execute the test in a dedicated temporary directory that is removed after each test.
author Martijn Pieters <mjpieters@fb.com>
date Thu, 23 Jun 2016 17:35:43 +0100
parents a109bf7e0dc2
children f21286e48bc6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
29194
3bea82dd4c4e py3: make tests/test-atomictempfile.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29188
diff changeset
1 from __future__ import absolute_import
3bea82dd4c4e py3: make tests/test-atomictempfile.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29188
diff changeset
2
3bea82dd4c4e py3: make tests/test-atomictempfile.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29188
diff changeset
3 import glob
14007
d764463b433e atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
diff changeset
4 import os
29391
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
5 import shutil
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
6 import tempfile
18666
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
7 import unittest
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
8
29194
3bea82dd4c4e py3: make tests/test-atomictempfile.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29188
diff changeset
9 from mercurial import (
3bea82dd4c4e py3: make tests/test-atomictempfile.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29188
diff changeset
10 util,
3bea82dd4c4e py3: make tests/test-atomictempfile.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29188
diff changeset
11 )
3bea82dd4c4e py3: make tests/test-atomictempfile.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29188
diff changeset
12 atomictempfile = util.atomictempfile
14007
d764463b433e atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
diff changeset
13
18666
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
14 class testatomictempfile(unittest.TestCase):
29391
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
15 def setUp(self):
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
16 self._testdir = tempfile.mkdtemp('atomictempfiletest')
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
17 self._filename = os.path.join(self._testdir, 'testfilename')
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
18
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
19 def tearDown(self):
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
20 shutil.rmtree(self._testdir, True)
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
21
18666
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
22 def test1_simple(self):
29391
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
23 file = atomictempfile(self._filename)
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
24 self.assertFalse(os.path.isfile(self._filename))
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
25 tempfilename = file._tempname
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
26 self.assertTrue(tempfilename in glob.glob(
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
27 os.path.join(self._testdir, '.testfilename-*')))
14007
d764463b433e atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
diff changeset
28
29188
f00f1de16454 tests: mark test-atomictempfile.py write as binary
timeless <timeless@mozdev.org>
parents: 18666
diff changeset
29 file.write(b'argh\n')
18666
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
30 file.close()
14007
d764463b433e atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
diff changeset
31
29391
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
32 self.assertTrue(os.path.isfile(self._filename))
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
33 self.assertTrue(tempfilename not in glob.glob(
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
34 os.path.join(self._testdir, '.testfilename-*')))
14007
d764463b433e atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
diff changeset
35
18666
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
36 # discard() removes the temp file without making the write permanent
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
37 def test2_discard(self):
29391
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
38 file = atomictempfile(self._filename)
18666
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
39 (dir, basename) = os.path.split(file._tempname)
14007
d764463b433e atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
diff changeset
40
29188
f00f1de16454 tests: mark test-atomictempfile.py write as binary
timeless <timeless@mozdev.org>
parents: 18666
diff changeset
41 file.write(b'yo\n')
18666
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
42 file.discard()
14007
d764463b433e atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
diff changeset
43
29391
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
44 self.assertFalse(os.path.isfile(self._filename))
18666
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
45 self.assertTrue(basename not in os.listdir('.'))
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
46
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
47 # if a programmer screws up and passes bad args to atomictempfile, they
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
48 # get a plain ordinary TypeError, not infinite recursion
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
49 def test3_oops(self):
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
50 self.assertRaises(TypeError, atomictempfile)
14007
d764463b433e atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
diff changeset
51
29201
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
52 # checkambig=True avoids ambiguity of timestamp
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
53 def test4_checkambig(self):
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
54 def atomicwrite(checkambig):
29391
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
55 f = atomictempfile(self._filename, checkambig=checkambig)
29201
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
56 f.write('FOO')
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
57 f.close()
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
58
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
59 # try some times, because reproduction of ambiguity depends on
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
60 # "filesystem time"
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
61 for i in xrange(5):
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
62 atomicwrite(False)
29391
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
63 oldstat = os.stat(self._filename)
29201
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
64 if oldstat.st_ctime != oldstat.st_mtime:
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
65 # subsequent changing never causes ambiguity
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
66 continue
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
67
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
68 repetition = 3
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
69
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
70 # repeat atomic write with checkambig=True, to examine
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
71 # whether st_mtime is advanced multiple times as expecetd
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
72 for j in xrange(repetition):
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
73 atomicwrite(True)
29391
1acf654f0985 atomictempfile: use a tempdir to keep the test environment clean
Martijn Pieters <mjpieters@fb.com>
parents: 29201
diff changeset
74 newstat = os.stat(self._filename)
29201
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
75 if oldstat.st_ctime != newstat.st_ctime:
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
76 # timestamp ambiguity was naturally avoided while repetition
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
77 continue
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
78
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
79 # st_mtime should be advanced "repetition" times, because
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
80 # all atomicwrite() occured at same time (in sec)
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
81 self.assertTrue(newstat.st_mtime ==
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
82 ((oldstat.st_mtime + repetition) & 0x7fffffff))
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
83 # no more examination is needed, if assumption above is true
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
84 break
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
85 else:
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
86 # This platform seems too slow to examine anti-ambiguity
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
87 # of file timestamp (or test happened to be executed at
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
88 # bad timing). Exit silently in this case, because running
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
89 # on other faster platforms can detect problems
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
90 pass
a109bf7e0dc2 util: make atomictempfile avoid ambiguity of file stat if needed
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29194
diff changeset
91
14007
d764463b433e atomictempfile: avoid infinite recursion in __del__().
Greg Ward <greg@gerg.ca>
parents:
diff changeset
92 if __name__ == '__main__':
29194
3bea82dd4c4e py3: make tests/test-atomictempfile.py use absolute_import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29188
diff changeset
93 import silenttestrunner
18666
fb9d1c2805ff test-atomictempfile: convert to unit test
Idan Kamara <idankk86@gmail.com>
parents: 15057
diff changeset
94 silenttestrunner.main(__name__)