1
# Copyright (C) 2006 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
"""Basic tests for AtomicFile"""
27
from . import TestCaseInTempDir, TestSkipped
30
class TestAtomicFile(TestCaseInTempDir):
32
def test_commit(self):
33
f = atomicfile.AtomicFile('test')
34
self.assertPathDoesNotExist('test')
38
self.assertEqual(['test'], os.listdir('.'))
39
self.check_file_contents('test', b'foo\n')
40
self.assertRaises(atomicfile.AtomicFileAlreadyClosed, f.commit)
41
self.assertRaises(atomicfile.AtomicFileAlreadyClosed, f.abort)
42
# close is re-entrant safe
46
f = atomicfile.AtomicFile('test')
49
self.assertEqual([], os.listdir('.'))
51
self.assertRaises(atomicfile.AtomicFileAlreadyClosed, f.abort)
52
self.assertRaises(atomicfile.AtomicFileAlreadyClosed, f.commit)
54
# close is re-entrant safe
58
f = atomicfile.AtomicFile('test')
60
# close on an open file is an abort
62
self.assertEqual([], os.listdir('.'))
64
self.assertRaises(atomicfile.AtomicFileAlreadyClosed, f.abort)
65
self.assertRaises(atomicfile.AtomicFileAlreadyClosed, f.commit)
67
# close is re-entrant safe
70
def test_text_mode(self):
71
f = atomicfile.AtomicFile('test', mode='wt')
75
contents = open('test', 'rb').read()
76
if sys.platform == 'win32':
77
self.assertEqual(b'foo\r\n', contents)
79
self.assertEqual(b'foo\n', contents)
81
def can_sys_preserve_mode(self):
82
# PLATFORM DEFICIENCY/ TestSkipped
83
return sys.platform not in ('win32',)
85
def _test_mode(self, mode):
86
if not self.can_sys_preserve_mode():
87
raise TestSkipped("This test cannot be run on your platform")
88
f = atomicfile.AtomicFile('test', mode='wb', new_mode=mode)
92
self.assertEqualMode(mode, stat.S_IMODE(st.st_mode))
94
def test_mode_0666(self):
95
self._test_mode(0o666)
97
def test_mode_0664(self):
98
self._test_mode(0o664)
100
def test_mode_0660(self):
101
self._test_mode(0o660)
103
def test_mode_0660(self):
104
self._test_mode(0o660)
106
def test_mode_0640(self):
107
self._test_mode(0o640)
109
def test_mode_0600(self):
110
self._test_mode(0o600)
112
def test_mode_0400(self):
113
self._test_mode(0o400)
114
# Make it read-write again so cleanup doesn't complain
115
os.chmod('test', 0o600)
117
def test_no_mode(self):
118
# The default file permissions should be based on umask
119
umask = osutils.get_umask()
120
f = atomicfile.AtomicFile('test', mode='wb')
123
st = os.lstat('test')
124
self.assertEqualMode(0o666 & ~umask, stat.S_IMODE(st.st_mode))
126
def test_context_manager_commit(self):
127
with atomicfile.AtomicFile('test') as f:
128
self.assertPathDoesNotExist('test')
131
self.assertEqual(['test'], os.listdir('.'))
132
self.check_file_contents('test', b'foo\n')
134
def test_context_manager_abort(self):
136
with atomicfile.AtomicFile('test') as f:
139
self.assertRaises(AssertionError, abort)
140
self.assertEqual([], os.listdir('.'))