11 from xattr import NS_USER, XATTR_CREATE, XATTR_REPLACE
13 if sys.hexversion >= 0x03000000:
20 TEST_DIR = os.environ.get("TEST_DIR", ".")
21 TEST_IGNORE_XATTRS = os.environ.get("TEST_IGNORE_XATTRS", "")
22 if TEST_IGNORE_XATTRS == "":
23 TEST_IGNORE_XATTRS = []
25 TEST_IGNORE_XATTRS = TEST_IGNORE_XATTRS.split(",")
26 # The following has to be a list comprehension, not a generator, to
27 # avoid weird consequences of lazy evaluation.
28 TEST_IGNORE_XATTRS.extend([a.encode() for a in TEST_IGNORE_XATTRS])
30 class xattrTest(unittest.TestCase):
32 USER_ATTR = NS_USER.decode() + "." + USER_NN
34 MANYOPS_COUNT = 131072
37 USER_NN = USER_NN.encode()
38 USER_VAL = USER_VAL.encode()
39 USER_ATTR = USER_ATTR.encode()
42 def _ignore_tuples(attrs):
43 """Remove ignored attributes from the output of xattr.get_all."""
44 return [attr for attr in attrs
45 if attr[0] not in TEST_IGNORE_XATTRS]
49 """Remove ignored attributes from the output of xattr.list"""
50 return [attr for attr in attrs
51 if attr not in TEST_IGNORE_XATTRS]
59 """tear down function"""
60 for fname in self.rmfiles:
63 except EnvironmentError:
65 for dname in self.rmdirs:
68 except EnvironmentError:
72 """create a temp file"""
73 fh, fname = tempfile.mkstemp(".test", "xattr-", TEST_DIR)
74 self.rmfiles.append(fname)
78 """create a temp dir"""
79 dname = tempfile.mkdtemp(".test", "xattr-", TEST_DIR)
80 self.rmdirs.append(dname)
83 def _getsymlink(self, dangling=True):
84 """create a symlink"""
85 fh, fname = self._getfile()
89 sname = fname + ".symlink"
90 os.symlink(fname, sname)
91 self.rmfiles.append(sname)
94 def _checkDeprecated(self, item, symlink=False):
95 """check deprecated list, set, get operations against an item"""
96 self.assertEqual(self._ignore(xattr.listxattr(item, symlink)),
98 self.assertRaises(EnvironmentError, xattr.setxattr, item,
99 self.USER_ATTR, self.USER_VAL,
102 xattr.setxattr(item, self.USER_ATTR, self.USER_VAL, 0, symlink)
104 err = sys.exc_info()[1]
105 if err.errno == errno.EPERM and symlink:
106 # symlinks may fail, in which case we abort the rest
107 # of the test for this case
110 self.assertRaises(EnvironmentError, xattr.setxattr, item,
111 self.USER_ATTR, self.USER_VAL, XATTR_CREATE)
112 self.assertEqual(self._ignore(xattr.listxattr(item, symlink)),
114 self.assertEqual(xattr.getxattr(item, self.USER_ATTR, symlink),
116 self.assertEqual(self._ignore_tuples(xattr.get_all(item,
118 [(self.USER_ATTR, self.USER_VAL)])
119 xattr.removexattr(item, self.USER_ATTR)
120 self.assertEqual(self._ignore(xattr.listxattr(item, symlink)),
122 self.assertEqual(self._ignore_tuples(xattr.get_all(item,
125 self.assertRaises(EnvironmentError, xattr.removexattr,
126 item, self.USER_ATTR)
128 def _checkListSetGet(self, item, symlink=False, use_ns=False):
129 """check list, set, get operations against an item"""
130 self.assertEqual(self._ignore(xattr.list(item, symlink)),
132 self.assertRaises(EnvironmentError, xattr.set, item,
133 self.USER_ATTR, self.USER_VAL, flags=XATTR_REPLACE)
134 self.assertRaises(EnvironmentError, xattr.set, item,
135 self.USER_NN, self.USER_VAL, flags=XATTR_REPLACE,
139 xattr.set(item, self.USER_NN, self.USER_VAL,
143 xattr.set(item, self.USER_ATTR, self.USER_VAL,
146 err = sys.exc_info()[1]
147 if err.errno == errno.EPERM and symlink:
148 # symlinks may fail, in which case we abort the rest
149 # of the test for this case
152 self.assertRaises(EnvironmentError, xattr.set, item,
153 self.USER_ATTR, self.USER_VAL, flags=XATTR_CREATE)
154 self.assertRaises(EnvironmentError, xattr.set, item,
155 self.USER_NN, self.USER_VAL,
156 flags=XATTR_CREATE, namespace=NS_USER)
157 self.assertEqual(self._ignore(xattr.list(item, nofollow=symlink)),
159 self.assertEqual(self._ignore(xattr.list(item, nofollow=symlink,
160 namespace=EMPTY_NS)),
162 self.assertEqual(xattr.list(item, namespace=NS_USER, nofollow=symlink),
164 self.assertEqual(xattr.get(item, self.USER_ATTR, nofollow=symlink),
166 self.assertEqual(xattr.get(item, self.USER_NN, nofollow=symlink,
167 namespace=NS_USER), self.USER_VAL)
168 self.assertEqual(self._ignore_tuples(xattr.get_all(item,
170 [(self.USER_ATTR, self.USER_VAL)])
171 self.assertEqual(xattr.get_all(item, nofollow=symlink,
173 [(self.USER_NN, self.USER_VAL)])
175 xattr.remove(item, self.USER_NN, namespace=NS_USER)
177 xattr.remove(item, self.USER_ATTR)
178 self.assertEqual(self._ignore(xattr.list(item, symlink)), [])
179 self.assertEqual(self._ignore_tuples(xattr.get_all(item,
182 self.assertRaises(EnvironmentError, xattr.remove,
183 item, self.USER_ATTR, nofollow=symlink)
184 self.assertRaises(EnvironmentError, xattr.remove, item,
185 self.USER_NN, namespace=NS_USER, nofollow=symlink)
187 def testNoXattrDeprecated(self):
188 """test no attributes (deprecated functions)"""
189 fh, fname = self._getfile()
190 self.assertEqual(self._ignore(xattr.listxattr(fname)), [])
191 self.assertEqual(self._ignore_tuples(xattr.get_all(fname)), [])
192 dname = self._getdir()
193 self.assertEqual(self._ignore(xattr.listxattr(dname)), [])
194 self.assertEqual(self._ignore_tuples(xattr.get_all(dname)), [])
195 _, sname = self._getsymlink()
196 self.assertEqual(self._ignore(xattr.listxattr(sname, True)), [])
197 self.assertEqual(self._ignore_tuples(xattr.get_all(sname,
201 def testNoXattr(self):
202 """test no attributes"""
203 fh, fname = self._getfile()
204 self.assertEqual(self._ignore(xattr.list(fname)), [])
205 self.assertEqual(xattr.list(fname, namespace=NS_USER), [])
206 self.assertEqual(self._ignore_tuples(xattr.get_all(fname)), [])
207 self.assertEqual(xattr.get_all(fname, namespace=NS_USER), [])
208 dname = self._getdir()
209 self.assertEqual(self._ignore(xattr.list(dname)), [])
210 self.assertEqual(xattr.list(dname, namespace=NS_USER), [])
211 self.assertEqual(self._ignore_tuples(xattr.get_all(dname)), [])
212 self.assertEqual(xattr.get_all(dname, namespace=NS_USER), [])
213 _, sname = self._getsymlink()
214 self.assertEqual(self._ignore(xattr.list(sname, nofollow=True)),
216 self.assertEqual(xattr.list(sname, nofollow=True,
217 namespace=NS_USER), [])
218 self.assertEqual(self._ignore_tuples(xattr.get_all(sname,
221 self.assertEqual(xattr.get_all(sname, nofollow=True,
222 namespace=NS_USER), [])
224 def testFileByNameDeprecated(self):
225 """test set and retrieve one attribute by file name (deprecated)"""
226 fh, fname = self._getfile()
227 self._checkDeprecated(fname)
230 def testFileByName(self):
231 """test set and retrieve one attribute by file name"""
232 fh, fname = self._getfile()
233 self._checkListSetGet(fname)
234 self._checkListSetGet(fname, use_ns=True)
237 def testFileByDescriptorDeprecated(self):
238 """test file descriptor operations (deprecated functions)"""
239 fh, fname = self._getfile()
240 self._checkDeprecated(fh)
243 def testFileByDescriptor(self):
244 """test file descriptor operations"""
245 fh, fname = self._getfile()
246 self._checkListSetGet(fh)
247 self._checkListSetGet(fh, use_ns=True)
250 def testFileByObjectDeprecated(self):
251 """test file descriptor operations (deprecated functions)"""
252 fh, fname = self._getfile()
254 self._checkDeprecated(fo)
257 def testFileByObject(self):
258 """test file descriptor operations"""
259 fh, fname = self._getfile()
261 self._checkListSetGet(fo)
262 self._checkListSetGet(fo, use_ns=True)
265 def testMixedAccessDeprecated(self):
266 """test mixed access to file (deprecated functions)"""
267 fh, fname = self._getfile()
269 self.assertEqual(self._ignore(xattr.listxattr(fname)), [])
270 xattr.setxattr(fname, self.USER_ATTR, self.USER_VAL)
271 self.assertEqual(self._ignore(xattr.listxattr(fh)),
273 self.assertEqual(xattr.getxattr(fo, self.USER_ATTR), self.USER_VAL)
274 self.assertEqual(self._ignore_tuples(xattr.get_all(fo)),
275 [(self.USER_ATTR, self.USER_VAL)])
276 self.assertEqual(self._ignore_tuples(xattr.get_all(fname)),
277 [(self.USER_ATTR, self.USER_VAL)])
280 def testMixedAccess(self):
281 """test mixed access to file"""
282 fh, fname = self._getfile()
284 self.assertEqual(self._ignore(xattr.list(fname)), [])
285 xattr.set(fname, self.USER_ATTR, self.USER_VAL)
286 self.assertEqual(self._ignore(xattr.list(fh)), [self.USER_ATTR])
287 self.assertEqual(xattr.list(fh, namespace=NS_USER), [self.USER_NN])
288 self.assertEqual(xattr.get(fo, self.USER_ATTR), self.USER_VAL)
289 self.assertEqual(xattr.get(fo, self.USER_NN, namespace=NS_USER),
291 self.assertEqual(self._ignore_tuples(xattr.get_all(fo)),
292 [(self.USER_ATTR, self.USER_VAL)])
293 self.assertEqual(xattr.get_all(fo, namespace=NS_USER),
294 [(self.USER_NN, self.USER_VAL)])
295 self.assertEqual(self._ignore_tuples(xattr.get_all(fname)),
296 [(self.USER_ATTR, self.USER_VAL)])
297 self.assertEqual(xattr.get_all(fname, namespace=NS_USER),
298 [(self.USER_NN, self.USER_VAL)])
301 def testDirOpsDeprecated(self):
302 """test attribute setting on directories (deprecated functions)"""
303 dname = self._getdir()
304 self._checkDeprecated(dname)
306 def testDirOps(self):
307 """test attribute setting on directories"""
308 dname = self._getdir()
309 self._checkListSetGet(dname)
310 self._checkListSetGet(dname, use_ns=True)
312 def testSymlinkOpsDeprecated(self):
313 """test symlink operations (deprecated functions)"""
314 _, sname = self._getsymlink()
315 self.assertRaises(EnvironmentError, xattr.listxattr, sname)
316 self._checkDeprecated(sname, symlink=True)
317 target, sname = self._getsymlink(dangling=False)
318 xattr.setxattr(target, self.USER_ATTR, self.USER_VAL)
319 self.assertEqual(self._ignore(xattr.listxattr(target)),
321 self.assertEqual(self._ignore(xattr.listxattr(sname, True)),
323 self.assertRaises(EnvironmentError, xattr.removexattr, sname,
324 self.USER_ATTR, True)
325 xattr.removexattr(sname, self.USER_ATTR, False)
327 def testSymlinkOps(self):
328 """test symlink operations"""
329 _, sname = self._getsymlink()
330 self.assertRaises(EnvironmentError, xattr.list, sname)
331 self._checkListSetGet(sname, symlink=True)
332 self._checkListSetGet(sname, symlink=True, use_ns=True)
333 target, sname = self._getsymlink(dangling=False)
334 xattr.set(target, self.USER_ATTR, self.USER_VAL)
335 self.assertEqual(self._ignore(xattr.list(target)), [self.USER_ATTR])
336 self.assertEqual(self._ignore(xattr.list(sname, nofollow=True)),
338 self.assertRaises(EnvironmentError, xattr.remove, sname,
339 self.USER_ATTR, nofollow=True)
340 xattr.remove(sname, self.USER_ATTR, nofollow=False)
342 def testBinaryPayloadDeprecated(self):
343 """test binary values (deprecated functions)"""
344 fh, fname = self._getfile()
346 BINVAL = "abc" + '\0' + "def"
348 BINVAL = BINVAL.encode()
349 xattr.setxattr(fname, self.USER_ATTR, BINVAL)
350 self.assertEqual(self._ignore(xattr.listxattr(fname)),
352 self.assertEqual(xattr.getxattr(fname, self.USER_ATTR), BINVAL)
353 self.assertEqual(self._ignore_tuples(xattr.get_all(fname)),
354 [(self.USER_ATTR, BINVAL)])
355 xattr.removexattr(fname, self.USER_ATTR)
357 def testBinaryPayload(self):
358 """test binary values"""
359 fh, fname = self._getfile()
361 BINVAL = "abc" + '\0' + "def"
363 BINVAL = BINVAL.encode()
364 xattr.set(fname, self.USER_ATTR, BINVAL)
365 self.assertEqual(self._ignore(xattr.list(fname)), [self.USER_ATTR])
366 self.assertEqual(xattr.list(fname, namespace=NS_USER), [self.USER_NN])
367 self.assertEqual(xattr.get(fname, self.USER_ATTR), BINVAL)
368 self.assertEqual(xattr.get(fname, self.USER_NN,
369 namespace=NS_USER), BINVAL)
370 self.assertEqual(self._ignore_tuples(xattr.get_all(fname)),
371 [(self.USER_ATTR, BINVAL)])
372 self.assertEqual(xattr.get_all(fname, namespace=NS_USER),
373 [(self.USER_NN, BINVAL)])
374 xattr.remove(fname, self.USER_ATTR)
376 def testManyOpsDeprecated(self):
377 """test many ops (deprecated functions)"""
378 fh, fname = self._getfile()
379 xattr.setxattr(fh, self.USER_ATTR, self.USER_VAL)
380 VL = [self.USER_ATTR]
381 for i in range(self.MANYOPS_COUNT):
382 self.assertEqual(self._ignore(xattr.listxattr(fh)), VL)
383 for i in range(self.MANYOPS_COUNT):
384 self.assertEqual(xattr.getxattr(fh, self.USER_ATTR), self.USER_VAL)
385 for i in range(self.MANYOPS_COUNT):
386 self.assertEqual(self._ignore_tuples(xattr.get_all(fh)),
387 [(self.USER_ATTR, self.USER_VAL)])
389 def testManyOps(self):
391 fh, fname = self._getfile()
392 xattr.set(fh, self.USER_ATTR, self.USER_VAL)
393 VL = [self.USER_ATTR]
395 for i in range(self.MANYOPS_COUNT):
396 self.assertEqual(self._ignore(xattr.list(fh)), VL)
397 self.assertEqual(self._ignore(xattr.list(fh,
398 namespace=EMPTY_NS)),
400 self.assertEqual(xattr.list(fh, namespace=NS_USER), VN)
401 for i in range(self.MANYOPS_COUNT):
402 self.assertEqual(xattr.get(fh, self.USER_ATTR), self.USER_VAL)
403 self.assertEqual(xattr.get(fh, self.USER_NN, namespace=NS_USER),
405 for i in range(self.MANYOPS_COUNT):
406 self.assertEqual(self._ignore_tuples(xattr.get_all(fh)),
407 [(self.USER_ATTR, self.USER_VAL)])
408 self.assertEqual(xattr.get_all(fh, namespace=NS_USER),
409 [(self.USER_NN, self.USER_VAL)])
411 def testNoneNamespace(self):
412 fh, fname = self._getfile()
413 self.assertRaises(TypeError, xattr.get, fh, self.USER_ATTR,
417 if __name__ == "__main__":