]> git.k1024.org Git - pylibacl.git/blob - test/test_acls.py
Try to enhance the FreeBSD support
[pylibacl.git] / test / test_acls.py
1 #
2 #
3
4 import unittest
5 import os
6 import tempfile
7
8 import posix1e
9
10 TEST_DIR=os.environ.get("TESTDIR", ".")
11
12
13 def has_from_mode(fn):
14     """Decorator to skip tests based on platform support"""
15     if not posix1e.HAS_ACL_FROM_MODE:
16         new_fn = lambda x: None
17         new_fn.__doc__ = "SKIPPED %s" % fn.__doc__
18         fn = new_fn
19     return fn
20
21
22 def has_acl_entry(fn):
23     """Decorator to skip tests based on platform support"""
24     if not posix1e.HAS_ACL_ENTRY:
25         new_fn = lambda x: None
26         new_fn.__doc__ = "SKIPPED %s" % fn.__doc__
27         fn = new_fn
28     return fn
29
30
31 def has_acl_check(fn):
32     """Decorator to skip tests based on platform support"""
33     if not posix1e.HAS_ACL_CHECK:
34         new_fn = lambda x: None
35         new_fn.__doc__ = "SKIPPED %s" % fn.__doc__
36         fn = new_fn
37     return fn
38
39
40 class aclTest:
41     """Support functions ACLs"""
42
43     def setUp(self):
44         """set up function"""
45         self.rmfiles = []
46         self.rmdirs = []
47
48     def tearDown(self):
49         """tear down function"""
50         for fname in self.rmfiles:
51             os.unlink(fname)
52         for dname in self.rmdirs:
53             os.rmdir(dname)
54
55     def _getfile(self):
56         """create a temp file"""
57         fh, fname = tempfile.mkstemp(".test", "xattr-", TEST_DIR)
58         self.rmfiles.append(fname)
59         return fh, fname
60
61     def _getdir(self):
62         """create a temp dir"""
63         dname = tempfile.mkdtemp(".test", "xattr-", TEST_DIR)
64         self.rmdirs.append(dname)
65         return dname
66
67     def _getsymlink(self):
68         """create a symlink"""
69         fh, fname = self._getfile()
70         os.close(fh)
71         os.unlink(fname)
72         os.symlink(fname + ".non-existent", fname)
73         return fname
74
75
76 class LoadTests(aclTest, unittest.TestCase):
77     """Load/create tests"""
78     def testFromFile(self):
79         """Test loading ACLs from a file"""
80         _, fname = self._getfile()
81         acl1 = posix1e.ACL(file=fname)
82         self.failUnless(acl1.valid(), "ACL read from file should be valid")
83
84     def testFromDir(self):
85         """Test loading ACLs from a directory"""
86         dname = self._getdir()
87         acl1 = posix1e.ACL(file=dname)
88         acl2 = posix1e.ACL(filedef=dname)
89         self.failUnless(acl1.valid(),
90                         "ACL read from directory should be valid")
91         # default ACLs might or might not be valid; missing ones are
92         # not valid, so we don't test acl2 for validity
93
94     def testFromFd(self):
95         """Test loading ACLs from a file descriptor"""
96         fd, _ = self._getfile()
97         acl1 = posix1e.ACL(fd=fd)
98         self.failUnless(acl1.valid(), "ACL read from fd should be valid")
99
100     def testFromEmpty(self):
101         """Test creating an empty ACL"""
102         acl1 = posix1e.ACL()
103         self.failIf(acl1.valid(), "Empty ACL should not be valid")
104
105     def testFromText(self):
106         """Test creating an ACL from text"""
107         acl1 = posix1e.ACL(text="u::rx,g::-,o::-")
108         self.failUnless(acl1.valid(),
109                         "ACL based on standard description should be valid")
110
111 class AclExtensions(aclTest, unittest.TestCase):
112     """ACL extensions checks"""
113
114     @has_from_mode
115     def testFromMode(self):
116         """Test loading ACLs from an octal mode"""
117         acl1 = posix1e.ACL(mode=0644)
118         self.failUnless(acl1.valid(),
119                         "ACL created via octal mode shoule be valid")
120
121     @has_acl_check
122     def testAclCheck(self):
123         """Test the acl_check method"""
124         acl1 = posix1e.ACL(text="u::rx,g::-,o::-")
125         self.failIf(acl1.check(), "ACL is not valid")
126         acl2 = posix1e.ACL()
127         self.failUnless(acl2.check(), "Empty ACL should not be valid")
128
129
130 class WriteTests(aclTest, unittest.TestCase):
131     """Write tests"""
132
133     def testDeleteDefault(self):
134         """Test removing the default ACL"""
135         dname = self._getdir()
136         posix1e.delete_default(dname)
137
138     def testReapply(self):
139         """Test re-applying an ACL"""
140         fd, fname = self._getfile()
141         acl1 = posix1e.ACL(fd=fd)
142         acl1.applyto(fd)
143         acl1.applyto(fname)
144         dname = self._getdir()
145         acl2 = posix1e.ACL(file=fname)
146         acl2.applyto(dname)
147
148
149 class ModificationTests(aclTest, unittest.TestCase):
150     """ACL modification tests"""
151
152     @has_acl_entry
153     def testAppend(self):
154         """Test append a new Entry to the ACL"""
155         acl = posix1e.ACL()
156         e = acl.append()
157         e.tag_type = posix1e.ACL_OTHER
158         acl.calc_mask()
159
160     @has_acl_entry
161     def testDelete(self):
162         """Test delete Entry from the ACL"""
163         acl = posix1e.ACL()
164         e = acl.append()
165         e.tag_type = posix1e.ACL_OTHER
166         acl.calc_mask()
167         acl.delete_entry(e)
168         acl.calc_mask()
169
170     @has_acl_entry
171     def testDoubleEntries(self):
172         """Test double entries"""
173         acl = posix1e.ACL(text="u::rx,g::-,o::-")
174         self.failUnless(acl.valid(), "ACL is not valid")
175         for tag_type in (posix1e.ACL_USER_OBJ, posix1e.ACL_GROUP_OBJ,
176                          posix1e.ACL_OTHER):
177             e = acl.append()
178             e.tag_type = tag_type
179             e.permset.clear()
180             self.failIf(acl.valid(),
181                         "ACL containing duplicate entries should not be valid")
182             acl.delete_entry(e)
183
184     @has_acl_entry
185     def testMultipleGoodEntries(self):
186         """Test multiple valid entries"""
187         acl = posix1e.ACL(text="u::rx,g::-,o::-")
188         self.failUnless(acl.valid(), "ACL is not valid")
189         for tag_type in (posix1e.ACL_USER,
190                          posix1e.ACL_GROUP):
191             for obj_id in range(5):
192                 e = acl.append()
193                 e.tag_type = tag_type
194                 e.qualifier = obj_id
195                 e.permset.clear()
196                 acl.calc_mask()
197                 self.failUnless(acl.valid(),
198                                "ACL should be able to hold multiple"
199                                 " user/group entries")
200     @has_acl_entry
201     def testMultipleBadEntries(self):
202         """Test multiple invalid entries"""
203         acl = posix1e.ACL(text="u::rx,g::-,o::-")
204         self.failUnless(acl.valid(), "ACL built from standard description"
205                         " should be valid")
206         for tag_type in (posix1e.ACL_USER,
207                          posix1e.ACL_GROUP):
208             e1 = acl.append()
209             e1.tag_type = tag_type
210             e1.qualifier = 0
211             e1.permset.clear()
212             acl.calc_mask()
213             self.failUnless(acl.valid(), "ACL should be able to add a"
214                             " user/group entry")
215             e2 = acl.append()
216             e2.tag_type = tag_type
217             e2.qualifier = 0
218             e2.permset.clear()
219             acl.calc_mask()
220             self.failIf(acl.valid(), "ACL should not validate when"
221                         " containing two duplicate entries")
222             acl.delete_entry(e1)
223             acl.delete_entry(e2)
224
225     @has_acl_entry
226     def testPermset(self):
227         """Test permissions"""
228         acl = posix1e.ACL()
229         e = acl.append()
230         ps = e.permset
231         ps.clear()
232         pmap = {
233             posix1e.ACL_READ: "read",
234             posix1e.ACL_WRITE: "write",
235             posix1e.ACL_EXECUTE: "execute",
236             }
237         for perm in pmap:
238             self.failIf(ps.test(perm), "Empty permission set should not"
239                         " have permission '%s'" % pmap[perm])
240             ps.add(perm)
241             self.failUnless(ps.test(perm), "Permission '%s' should exist"
242                         " after addition" % pmap[perm])
243             ps.delete(perm)
244             self.failIf(ps.test(perm), "Permission '%s' should not exist"
245                         " after deletion" % pmap[perm])
246
247
248 if __name__ == "__main__":
249     unittest.main()