~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_permissions.py

  • Committer: Aaron Bentley
  • Date: 2006-08-25 21:51:18 UTC
  • mto: This revision was merged to the branch mainline in revision 1997.
  • Revision ID: aaron.bentley@utoronto.ca-20060825215118-352f6465e332ac0a
Retrieve only 500 revision trees at once

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 Canonical Ltd
 
1
# Copyright (C) 2005 by Canonical Ltd
2
2
# -*- coding: utf-8 -*-
3
3
#
4
4
# This program is free software; you can redistribute it and/or modify
13
13
#
14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
17
 
18
18
 
19
19
"""Tests for bzr setting permissions.
26
26
"""
27
27
 
28
28
# TODO: jam 20051215 There are no tests for ftp yet, because we have no ftp server
29
 
# TODO: jam 20051215 Currently the default behavior for 'bzr branch' is just
 
29
# TODO: jam 20051215 Currently the default behavior for 'bzr branch' is just 
30
30
#                    defined by the local umask. This isn't terrible, is it
31
31
#                    the truly desired behavior?
32
 
 
 
32
 
33
33
import os
34
34
import sys
 
35
import stat
 
36
from StringIO import StringIO
 
37
import urllib
35
38
 
36
 
from bzrlib import urlutils
37
39
from bzrlib.branch import Branch
38
 
from bzrlib.controldir import ControlDir
 
40
from bzrlib.bzrdir import BzrDir
 
41
from bzrlib.lockable_files import LockableFiles, TransportLock
39
42
from bzrlib.tests import TestCaseWithTransport, TestSkipped
40
43
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
 
44
from bzrlib.transport import get_transport
41
45
from bzrlib.workingtree import WorkingTree
42
46
 
43
47
 
44
48
def chmod_r(base, file_mode, dir_mode):
45
49
    """Recursively chmod from a base directory"""
 
50
    assert os.path.isdir(base)
46
51
    os.chmod(base, dir_mode)
47
52
    for root, dirs, files in os.walk(base):
48
53
        for d in dirs:
62
67
    :param dir_mode: The mode for all directories
63
68
    :param include_base: If false, only check the subdirectories
64
69
    """
65
 
    t = test.get_transport()
 
70
    assert os.path.isdir(base)
 
71
    t = get_transport(".")
66
72
    if include_base:
67
73
        test.assertTransportMode(t, base, dir_mode)
68
74
    for root, dirs, files in os.walk(base):
69
75
        for d in dirs:
70
 
            p = '/'.join([urlutils.quote(x) for x in root.split('/\\') + [d]])
 
76
            p = '/'.join([urllib.quote(x) for x in root.split('/\\') + [d]])
71
77
            test.assertTransportMode(t, p, dir_mode)
72
78
        for f in files:
73
79
            p = os.path.join(root, f)
74
 
            p = '/'.join([urlutils.quote(x) for x in root.split('/\\') + [f]])
 
80
            p = '/'.join([urllib.quote(x) for x in root.split('/\\') + [f]])
75
81
            test.assertTransportMode(t, p, file_mode)
76
82
 
77
83
 
83
89
 
84
90
        t = self.make_branch_and_tree('.')
85
91
        b = t.branch
86
 
        with open('a', 'wb') as f: f.write('foo\n')
 
92
        open('a', 'wb').write('foo\n')
87
93
        # ensure check_mode_r works with capital-letter file-ids like TREE_ROOT
88
94
        t.add('a', 'CAPS-ID')
89
95
        t.commit('foo')
93
99
 
94
100
        # although we are modifying the filesystem
95
101
        # underneath the objects, they are not locked, and thus it must
96
 
        # be safe for most operations. But here we want to observe a
 
102
        # be safe for most operations. But here we want to observe a 
97
103
        # mode change in the control bits, which current do not refresh
98
104
        # when a new lock is taken out.
99
105
        t = WorkingTree.open('.')
100
106
        b = t.branch
101
107
        self.assertEqualMode(0755, b.control_files._dir_mode)
102
108
        self.assertEqualMode(0644, b.control_files._file_mode)
103
 
        self.assertEqualMode(0755, b.bzrdir._get_dir_mode())
104
 
        self.assertEqualMode(0644, b.bzrdir._get_file_mode())
105
109
 
106
110
        # Modifying a file shouldn't break the permissions
107
 
        with open('a', 'wb') as f: f.write('foo2\n')
 
111
        open('a', 'wb').write('foo2\n')
108
112
        t.commit('foo2')
109
113
        # The mode should be maintained after commit
110
114
        check_mode_r(self, '.bzr', 0644, 0755)
111
115
 
112
116
        # Adding a new file should maintain the permissions
113
 
        with open('b', 'wb') as f: f.write('new b\n')
 
117
        open('b', 'wb').write('new b\n')
114
118
        t.add('b')
115
119
        t.commit('new b')
116
120
        check_mode_r(self, '.bzr', 0644, 0755)
122
126
        b = t.branch
123
127
        self.assertEqualMode(0775, b.control_files._dir_mode)
124
128
        self.assertEqualMode(0664, b.control_files._file_mode)
125
 
        self.assertEqualMode(0775, b.bzrdir._get_dir_mode())
126
 
        self.assertEqualMode(0664, b.bzrdir._get_file_mode())
127
129
 
128
 
        with open('a', 'wb') as f: f.write('foo3\n')
 
130
        open('a', 'wb').write('foo3\n')
129
131
        t.commit('foo3')
130
132
        check_mode_r(self, '.bzr', 0664, 0775)
131
133
 
132
 
        with open('c', 'wb') as f: f.write('new c\n')
 
134
        open('c', 'wb').write('new c\n')
133
135
        t.add('c')
134
136
        t.commit('new c')
135
137
        check_mode_r(self, '.bzr', 0664, 0775)
136
138
 
137
 
    def test_new_files_group_sticky_bit(self):
138
 
        if sys.platform == 'win32':
139
 
            raise TestSkipped('chmod has no effect on win32')
140
 
        elif sys.platform == 'darwin' or 'freebsd' in sys.platform:
141
 
            # FreeBSD-based platforms create temp dirs with the 'wheel' group,
142
 
            # which users are not likely to be in, and this prevents us from
143
 
            # setting the sgid bit
144
 
            os.chown(self.test_dir, os.getuid(), os.getgid())
145
 
 
146
 
        t = self.make_branch_and_tree('.')
147
 
        b = t.branch
148
 
 
149
139
        # Test the group sticky bit
150
140
        # Recursively update the modes of all files
151
141
        chmod_r('.bzr', 0664, 02775)
154
144
        b = t.branch
155
145
        self.assertEqualMode(02775, b.control_files._dir_mode)
156
146
        self.assertEqualMode(0664, b.control_files._file_mode)
157
 
        self.assertEqualMode(02775, b.bzrdir._get_dir_mode())
158
 
        self.assertEqualMode(0664, b.bzrdir._get_file_mode())
159
147
 
160
 
        with open('a', 'wb') as f: f.write('foo4\n')
 
148
        open('a', 'wb').write('foo4\n')
161
149
        t.commit('foo4')
162
150
        check_mode_r(self, '.bzr', 0664, 02775)
163
151
 
164
 
        with open('d', 'wb') as f: f.write('new d\n')
 
152
        open('d', 'wb').write('new d\n')
165
153
        t.add('d')
166
154
        t.commit('new d')
167
155
        check_mode_r(self, '.bzr', 0664, 02775)
168
156
 
 
157
    def test_disable_set_mode(self):
 
158
        # TODO: jam 20051215 Ultimately, this test should probably test that
 
159
        #                    extra chmod calls aren't being made
 
160
        try:
 
161
            transport = get_transport(self.get_url())
 
162
            transport.put('my-lock', StringIO(''))
 
163
            lockable = LockableFiles(transport, 'my-lock', TransportLock)
 
164
            self.assertNotEqual(None, lockable._dir_mode)
 
165
            self.assertNotEqual(None, lockable._file_mode)
 
166
 
 
167
            LockableFiles._set_dir_mode = False
 
168
            transport = get_transport('.')
 
169
            lockable = LockableFiles(transport, 'my-lock', TransportLock)
 
170
            self.assertEqual(None, lockable._dir_mode)
 
171
            self.assertNotEqual(None, lockable._file_mode)
 
172
 
 
173
            LockableFiles._set_file_mode = False
 
174
            transport = get_transport('.')
 
175
            lockable = LockableFiles(transport, 'my-lock', TransportLock)
 
176
            self.assertEqual(None, lockable._dir_mode)
 
177
            self.assertEqual(None, lockable._file_mode)
 
178
 
 
179
            LockableFiles._set_dir_mode = True
 
180
            transport = get_transport('.')
 
181
            lockable = LockableFiles(transport, 'my-lock', TransportLock)
 
182
            self.assertNotEqual(None, lockable._dir_mode)
 
183
            self.assertEqual(None, lockable._file_mode)
 
184
 
 
185
            LockableFiles._set_file_mode = True
 
186
            transport = get_transport('.')
 
187
            lockable = LockableFiles(transport, 'my-lock', TransportLock)
 
188
            self.assertNotEqual(None, lockable._dir_mode)
 
189
            self.assertNotEqual(None, lockable._file_mode)
 
190
        finally:
 
191
            LockableFiles._set_dir_mode = True
 
192
            LockableFiles._set_file_mode = True
 
193
 
169
194
 
170
195
class TestSftpPermissions(TestCaseWithSFTPServer):
171
196
 
177
202
 
178
203
        # bodge around for stubsftpserver not letting use connect
179
204
        # more than once
180
 
        _t = self.get_transport()
 
205
        _t = get_transport(self.get_url())
181
206
 
182
207
        os.mkdir('local')
183
208
        t_local = self.make_branch_and_tree('local')
184
209
        b_local = t_local.branch
185
 
        with open('local/a', 'wb') as f: f.write('foo\n')
 
210
        open('local/a', 'wb').write('foo\n')
186
211
        t_local.add('a')
187
212
        t_local.commit('foo')
188
213
 
194
219
        b_local = t.branch
195
220
        self.assertEqualMode(0755, b_local.control_files._dir_mode)
196
221
        self.assertEqualMode(0644, b_local.control_files._file_mode)
197
 
        self.assertEqualMode(0755, b_local.bzrdir._get_dir_mode())
198
 
        self.assertEqualMode(0644, b_local.bzrdir._get_file_mode())
199
222
 
200
223
        os.mkdir('sftp')
201
224
        sftp_url = self.get_url('sftp')
202
 
        b_sftp = ControlDir.create_branch_and_repo(sftp_url)
 
225
        b_sftp = BzrDir.create_branch_and_repo(sftp_url)
203
226
 
204
227
        b_sftp.pull(b_local)
205
228
        del b_sftp
209
232
        b_sftp = Branch.open(sftp_url)
210
233
        self.assertEqualMode(0755, b_sftp.control_files._dir_mode)
211
234
        self.assertEqualMode(0644, b_sftp.control_files._file_mode)
212
 
        self.assertEqualMode(0755, b_sftp.bzrdir._get_dir_mode())
213
 
        self.assertEqualMode(0644, b_sftp.bzrdir._get_file_mode())
214
235
 
215
 
        with open('local/a', 'wb') as f: f.write('foo2\n')
 
236
        open('local/a', 'wb').write('foo2\n')
216
237
        t_local.commit('foo2')
217
238
        b_sftp.pull(b_local)
218
239
        # The mode should be maintained after commit
219
240
        check_mode_r(self, 'sftp/.bzr', 0644, 0755)
220
241
 
221
 
        with open('local/b', 'wb') as f: f.write('new b\n')
 
242
        open('local/b', 'wb').write('new b\n')
222
243
        t_local.add('b')
223
244
        t_local.commit('new b')
224
245
        b_sftp.pull(b_local)
232
253
        b_sftp = Branch.open(sftp_url)
233
254
        self.assertEqualMode(0775, b_sftp.control_files._dir_mode)
234
255
        self.assertEqualMode(0664, b_sftp.control_files._file_mode)
235
 
        self.assertEqualMode(0775, b_sftp.bzrdir._get_dir_mode())
236
 
        self.assertEqualMode(0664, b_sftp.bzrdir._get_file_mode())
237
256
 
238
 
        with open('local/a', 'wb') as f: f.write('foo3\n')
 
257
        open('local/a', 'wb').write('foo3\n')
239
258
        t_local.commit('foo3')
240
259
        b_sftp.pull(b_local)
241
260
        check_mode_r(self, 'sftp/.bzr', 0664, 0775)
242
261
 
243
 
        with open('local/c', 'wb') as f: f.write('new c\n')
 
262
        open('local/c', 'wb').write('new c\n')
244
263
        t_local.add('c')
245
264
        t_local.commit('new c')
246
265
        b_sftp.pull(b_local)
254
273
        original_umask = os.umask(umask)
255
274
 
256
275
        try:
257
 
            t = self.get_transport()
 
276
            t = get_transport(self.get_url())
258
277
            # Direct access should be masked by umask
259
278
            t._sftp_open_exclusive('a', mode=0666).write('foo\n')
260
279
            self.assertTransportMode(t, 'a', 0666 &~umask)
261
280
 
262
281
            # but Transport overrides umask
263
 
            t.put_bytes('b', 'txt', mode=0666)
 
282
            t.put('b', 'txt', mode=0666)
264
283
            self.assertTransportMode(t, 'b', 0666)
265
284
 
266
 
            t._get_sftp().mkdir('c', mode=0777)
 
285
            t._sftp.mkdir('c', mode=0777)
267
286
            self.assertTransportMode(t, 'c', 0777 &~umask)
268
287
 
269
288
            t.mkdir('d', mode=0777)