tests: fixing broken tests.
[rrq/fuse_xattrs.git] / test / tests.py
1 #!/usr/bin/env python3
2
3
4 # fuse_xattrs - Add xattrs support using sidecar files
5 #
6 # Copyright (C) 2016  Felipe Barriga Richards <felipe {at} felipebarriga.cl>
7 #
8 # This program can be distributed under the terms of the GNU GPL.
9 # See the file COPYING.
10
11
12 import unittest
13 import xattr
14 from pathlib import Path
15 import os
16
17 # TODO
18 # - listxattr: list too long
19 # - sidecar file permissions
20 # - corrupt metadata files
21
22
23 class TestXAttrs(unittest.TestCase):
24     def setUp(self):
25         self.randomFile = "./mount/foo.txt"
26         self.randomFileSidecar = "./mount/foo.txt.xattr"
27         if os.path.isfile(self.randomFile):
28             os.remove(self.randomFile)
29         Path(self.randomFile).touch()
30
31         if os.path.isfile(self.randomFileSidecar):
32             os.remove(self.randomFileSidecar)
33
34     def tearDown(self):
35         os.remove(self.randomFile)
36         if os.path.isfile(self.randomFileSidecar):
37             os.remove(self.randomFileSidecar)
38
39     def test_xattr_set(self):
40         xattr.setxattr(self.randomFile, "user.foo", bytes("bar", "utf-8"))
41
42     def test_xattr_set_name_max_length(self):
43         enc = "utf-8"
44         key = "user." + "x" * 250
45         value = "x"
46         self.assertEqual(len(key), 255)
47         xattr.setxattr(self.randomFile, key, bytes(value, enc))
48
49         key = "user." + "x" * 251
50         self.assertEqual(len(key), 256)
51         with self.assertRaises(OSError) as ex:
52             xattr.setxattr(self.randomFile, key, bytes(value, enc))
53         self.assertEqual(ex.exception.errno, 34)
54         self.assertEqual(ex.exception.strerror, "Numerical result out of range")
55
56     @unittest.expectedFailure
57     def test_xattr_set_value_max_size(self):
58         enc = "utf-8"
59         key = "user.foo"
60         value = "x" * (64 * 1024 + 1)  # we want max 64KiB of data
61         with self.assertRaises(OSError) as ex:
62             xattr.setxattr(self.randomFile, key, bytes(value, enc))
63
64         # on btrfs we get "no space left on device"
65         self.assertEqual(ex.exception.errno, 28)
66         self.assertEqual(ex.exception.strerror, "No space left on device")
67
68         # on fuse_xattr we get "Argument list too long"
69         # the error is thrown by fuse, not by fuse_xattr code
70
71     def test_xattr_set_namespaces(self):
72         with self.assertRaises(OSError) as ex:
73             xattr.setxattr(self.randomFile, "system.foo", bytes("bar", "utf-8"))
74         self.assertEqual(ex.exception.errno, 95)
75         self.assertEqual(ex.exception.strerror, "Operation not supported")
76
77         with self.assertRaises(OSError) as ex:
78             xattr.setxattr(self.randomFile, "trust.foo", bytes("bar", "utf-8"))
79         self.assertEqual(ex.exception.errno, 95)
80         self.assertEqual(ex.exception.strerror, "Operation not supported")
81
82         with self.assertRaises(OSError) as ex:
83             xattr.setxattr(self.randomFile, "foo.foo", bytes("bar", "utf-8"))
84         self.assertEqual(ex.exception.errno, 95)
85         self.assertEqual(ex.exception.strerror, "Operation not supported")
86
87         with self.assertRaises(PermissionError) as ex:
88             xattr.setxattr(self.randomFile, "security.foo", bytes("bar", "utf-8"))
89         self.assertEqual(ex.exception.errno, 1)
90         self.assertEqual(ex.exception.strerror, "Operation not permitted")
91
92     def test_xattr_get_non_existent(self):
93         key = "user.foo"
94         with self.assertRaises(OSError) as ex:
95             xattr.getxattr(self.randomFile, key)
96         self.assertEqual(ex.exception.errno, 61)
97         self.assertEqual(ex.exception.strerror, "No data available")
98
99     def test_xattr_get(self):
100         enc = "utf-8"
101         key = "user.foo"
102         value = "bar"
103         xattr.setxattr(self.randomFile, key, bytes(value, enc))
104         read_value = xattr.getxattr(self.randomFile, key)
105         self.assertEqual(value, read_value.decode(enc))
106
107     def test_xattr_set_override(self):
108         enc = "utf-8"
109         key = "user.foo"
110         value1 = "bar"
111         value2 = "rab"
112         xattr.setxattr(self.randomFile, key, bytes(value1, enc))
113         xattr.setxattr(self.randomFile, key, bytes(value2, enc))
114         read_value = xattr.getxattr(self.randomFile, key)
115         self.assertEqual(value2, read_value.decode(enc))
116
117     def test_xattr_set_create(self):
118         enc = "utf-8"
119         key = "user.foo"
120         value1 = "bar"
121         value2 = "rab"
122         xattr.setxattr(self.randomFile, key, bytes(value1, enc), xattr.XATTR_CREATE)
123         with self.assertRaises(FileExistsError) as ex:
124             xattr.setxattr(self.randomFile, key, bytes(value2, enc), xattr.XATTR_CREATE)
125         self.assertEqual(ex.exception.errno, 17)
126         self.assertEqual(ex.exception.strerror, "File exists")
127
128         read_value = xattr.getxattr(self.randomFile, key)
129         self.assertEqual(value1, read_value.decode(enc))
130
131     def test_xattr_set_replace(self):
132         enc = "utf-8"
133         key = "user.foo"
134         value = "bar"
135         with self.assertRaises(OSError) as ex:
136             xattr.setxattr(self.randomFile, key, bytes(value, enc), xattr.XATTR_REPLACE)
137         self.assertEqual(ex.exception.errno, 61)
138         self.assertEqual(ex.exception.strerror, "No data available")
139
140         with self.assertRaises(OSError) as ex:
141             xattr.getxattr(self.randomFile, key)
142         self.assertEqual(ex.exception.errno, 61)
143         self.assertEqual(ex.exception.strerror, "No data available")
144
145     def test_xattr_list_empty(self):
146         attrs = xattr.listxattr(self.randomFile)
147         self.assertEqual(len(attrs), 0)
148
149     def test_xattr_list(self):
150         enc = "utf-8"
151         key1 = b"user.foo"
152         key2 = b"user.foo2"
153         key3 = b"user.foo3"
154         value = "bar"
155
156         # set 3 keys
157         xattr.setxattr(self.randomFile, key1, bytes(value, enc))
158         xattr.setxattr(self.randomFile, key2, bytes(value, enc))
159         xattr.setxattr(self.randomFile, key3, bytes(value, enc))
160
161         # get and check the list
162         attrs = xattr.listxattr(self.randomFile)
163
164         self.assertEqual(len(attrs), 3)
165         self.assertTrue(key1 in attrs)
166         self.assertTrue(key2 in attrs)
167         self.assertTrue(key3 in attrs)
168
169     def test_xattr_unicode(self):
170         enc = "utf-8"
171         key = "user.fooシüßてЙĘ𝄠✠"
172         value = "bar"
173
174         # set
175         xattr.setxattr(self.randomFile, key, bytes(value, enc))
176
177         # list
178         attrs = xattr.listxattr(self.randomFile)
179         self.assertEqual(len(attrs), 1)
180         self.assertTrue(key.encode() in attrs)
181
182         # read
183         read_value = xattr.getxattr(self.randomFile, key)
184         self.assertEqual(value, read_value.decode(enc))
185
186         # remove
187         xattr.removexattr(self.randomFile, key)
188
189     def test_xattr_remove(self):
190         enc = "utf-8"
191         key = "user.foo"
192         value = "bar"
193
194         # set
195         xattr.setxattr(self.randomFile, key, bytes(value, enc))
196
197         # remove
198         xattr.removexattr(self.randomFile, key)
199
200         # list should be empty
201         attrs = xattr.listxattr(self.randomFile)
202         self.assertEqual(len(attrs), 0)
203
204         # should fail when trying to read it
205         with self.assertRaises(OSError) as ex:
206             xattr.getxattr(self.randomFile, key)
207         self.assertEqual(ex.exception.errno, 61)
208         self.assertEqual(ex.exception.strerror, "No data available")
209
210         # removing twice should fail
211         with self.assertRaises(OSError) as ex:
212             xattr.getxattr(self.randomFile, key)
213         self.assertEqual(ex.exception.errno, 61)
214         self.assertEqual(ex.exception.strerror, "No data available")
215
216
217 if __name__ == '__main__':
218     unittest.main()