11 TEST_DIR=os.environ.get("TESTDIR", ".")
13 BASIC_ACL_TEXT="u::rw,g::r,o::-"
16 """Wrapper to skip a test"""
17 new_fn = lambda x: None
18 new_fn.__doc__ = "SKIPPED %s" % fn.__doc__
22 def has_ext(extension):
23 """Decorator to skip tests based on platform support"""
31 """Support functions ACLs"""
39 """tear down function"""
40 for fname in self.rmfiles:
42 for dname in self.rmdirs:
46 """create a temp file"""
47 fh, fname = tempfile.mkstemp(".test", "xattr-", TEST_DIR)
48 self.rmfiles.append(fname)
52 """create a temp dir"""
53 dname = tempfile.mkdtemp(".test", "xattr-", TEST_DIR)
54 self.rmdirs.append(dname)
57 def _getsymlink(self):
58 """create a symlink"""
59 fh, fname = self._getfile()
62 os.symlink(fname + ".non-existent", fname)
66 class LoadTests(aclTest, unittest.TestCase):
67 """Load/create tests"""
68 def testFromFile(self):
69 """Test loading ACLs from a file"""
70 _, fname = self._getfile()
71 acl1 = posix1e.ACL(file=fname)
72 self.failUnless(acl1.valid(), "ACL read from file should be valid")
74 def testFromDir(self):
75 """Test loading ACLs from a directory"""
76 dname = self._getdir()
77 acl1 = posix1e.ACL(file=dname)
78 acl2 = posix1e.ACL(filedef=dname)
79 self.failUnless(acl1.valid(),
80 "ACL read from directory should be valid")
81 # default ACLs might or might not be valid; missing ones are
82 # not valid, so we don't test acl2 for validity
85 """Test loading ACLs from a file descriptor"""
86 fd, _ = self._getfile()
87 acl1 = posix1e.ACL(fd=fd)
88 self.failUnless(acl1.valid(), "ACL read from fd should be valid")
90 def testFromEmpty(self):
91 """Test creating an empty ACL"""
93 self.failIf(acl1.valid(), "Empty ACL should not be valid")
95 def testFromText(self):
96 """Test creating an ACL from text"""
97 acl1 = posix1e.ACL(text=BASIC_ACL_TEXT)
98 self.failUnless(acl1.valid(),
99 "ACL based on standard description should be valid")
101 class AclExtensions(aclTest, unittest.TestCase):
102 """ACL extensions checks"""
104 @has_ext(HAS_ACL_FROM_MODE)
105 def testFromMode(self):
106 """Test loading ACLs from an octal mode"""
107 acl1 = posix1e.ACL(mode=0644)
108 self.failUnless(acl1.valid(),
109 "ACL created via octal mode shoule be valid")
111 @has_ext(HAS_ACL_CHECK)
112 def testAclCheck(self):
113 """Test the acl_check method"""
114 acl1 = posix1e.ACL(text=BASIC_ACL_TEXT)
115 self.failIf(acl1.check(), "ACL is not valid")
117 self.failUnless(acl2.check(), "Empty ACL should not be valid")
119 @has_ext(HAS_EXTENDED_CHECK)
120 def testExtended(self):
121 """Test the acl_extended function"""
122 fd, fname = self._getfile()
123 basic_acl = posix1e.ACL(text=BASIC_ACL_TEXT)
124 basic_acl.applyto(fd)
125 for item in fd, fname:
126 self.failIf(has_extended(item),
127 "A simple ACL should not be reported as extended")
128 enhanced_acl = posix1e.ACL(text="u::rw,g::-,o::-,u:root:rw,mask::r")
129 self.failUnless(enhanced_acl.valid(),
130 "Failure to build an extended ACL")
131 enhanced_acl.applyto(fd)
132 for item in fd, fname:
133 self.failUnless(has_extended(item),
134 "An extended ACL should be reported as such")
136 @has_ext(HAS_EQUIV_MODE)
137 def testEquivMode(self):
138 """Test the equiv_mode function"""
139 if HAS_ACL_FROM_MODE:
140 for mode in 0644, 0755:
141 acl = posix1e.ACL(mode=mode)
142 self.failUnlessEqual(acl.equiv_mode(), mode)
143 acl = posix1e.ACL(text="u::rw,g::r,o::r")
144 self.failUnlessEqual(acl.equiv_mode(), 0644)
145 acl = posix1e.ACL(text="u::rx,g::-,o::-")
146 self.failUnlessEqual(acl.equiv_mode(), 0500)
149 class WriteTests(aclTest, unittest.TestCase):
152 def testDeleteDefault(self):
153 """Test removing the default ACL"""
154 dname = self._getdir()
155 posix1e.delete_default(dname)
157 def testReapply(self):
158 """Test re-applying an ACL"""
159 fd, fname = self._getfile()
160 acl1 = posix1e.ACL(fd=fd)
163 dname = self._getdir()
164 acl2 = posix1e.ACL(file=fname)
168 class ModificationTests(aclTest, unittest.TestCase):
169 """ACL modification tests"""
171 @has_ext(HAS_ACL_ENTRY)
172 def testAppend(self):
173 """Test append a new Entry to the ACL"""
176 e.tag_type = posix1e.ACL_OTHER
179 @has_ext(HAS_ACL_ENTRY)
180 def testDelete(self):
181 """Test delete Entry from the ACL"""
184 e.tag_type = posix1e.ACL_OTHER
189 @has_ext(HAS_ACL_ENTRY)
190 def testDoubleEntries(self):
191 """Test double entries"""
192 acl = posix1e.ACL(text=BASIC_ACL_TEXT)
193 self.failUnless(acl.valid(), "ACL is not valid")
194 for tag_type in (posix1e.ACL_USER_OBJ, posix1e.ACL_GROUP_OBJ,
197 e.tag_type = tag_type
199 self.failIf(acl.valid(),
200 "ACL containing duplicate entries should not be valid")
203 @has_ext(HAS_ACL_ENTRY)
204 def testMultipleGoodEntries(self):
205 """Test multiple valid entries"""
206 acl = posix1e.ACL(text=BASIC_ACL_TEXT)
207 self.failUnless(acl.valid(), "ACL is not valid")
208 for tag_type in (posix1e.ACL_USER,
210 for obj_id in range(5):
212 e.tag_type = tag_type
216 self.failUnless(acl.valid(),
217 "ACL should be able to hold multiple"
218 " user/group entries")
220 @has_ext(HAS_ACL_ENTRY)
221 def testMultipleBadEntries(self):
222 """Test multiple invalid entries"""
223 acl = posix1e.ACL(text=BASIC_ACL_TEXT)
224 self.failUnless(acl.valid(), "ACL built from standard description"
226 for tag_type in (posix1e.ACL_USER,
229 e1.tag_type = tag_type
233 self.failUnless(acl.valid(), "ACL should be able to add a"
236 e2.tag_type = tag_type
240 self.failIf(acl.valid(), "ACL should not validate when"
241 " containing two duplicate entries")
245 @has_ext(HAS_ACL_ENTRY)
246 def testPermset(self):
247 """Test permissions"""
253 posix1e.ACL_READ: "read",
254 posix1e.ACL_WRITE: "write",
255 posix1e.ACL_EXECUTE: "execute",
258 self.failIf(ps.test(perm), "Empty permission set should not"
259 " have permission '%s'" % pmap[perm])
261 self.failUnless(ps.test(perm), "Permission '%s' should exist"
262 " after addition" % pmap[perm])
264 self.failIf(ps.test(perm), "Permission '%s' should not exist"
265 " after deletion" % pmap[perm])
268 if __name__ == "__main__":