1 | import unittest
|
---|
2 | import os
|
---|
3 | from test.test_support import TESTFN, run_unittest
|
---|
4 | import stat
|
---|
5 |
|
---|
6 | class TestFilemode(unittest.TestCase):
|
---|
7 | file_flags = {'SF_APPEND', 'SF_ARCHIVED', 'SF_IMMUTABLE', 'SF_NOUNLINK',
|
---|
8 | 'SF_SNAPSHOT', 'UF_APPEND', 'UF_COMPRESSED', 'UF_HIDDEN',
|
---|
9 | 'UF_IMMUTABLE', 'UF_NODUMP', 'UF_NOUNLINK', 'UF_OPAQUE'}
|
---|
10 |
|
---|
11 | formats = {'S_IFBLK', 'S_IFCHR', 'S_IFDIR', 'S_IFIFO', 'S_IFLNK',
|
---|
12 | 'S_IFREG', 'S_IFSOCK'}
|
---|
13 |
|
---|
14 | format_funcs = {'S_ISBLK', 'S_ISCHR', 'S_ISDIR', 'S_ISFIFO', 'S_ISLNK',
|
---|
15 | 'S_ISREG', 'S_ISSOCK'}
|
---|
16 |
|
---|
17 | stat_struct = {
|
---|
18 | 'ST_MODE': 0,
|
---|
19 | 'ST_INO': 1,
|
---|
20 | 'ST_DEV': 2,
|
---|
21 | 'ST_NLINK': 3,
|
---|
22 | 'ST_UID': 4,
|
---|
23 | 'ST_GID': 5,
|
---|
24 | 'ST_SIZE': 6,
|
---|
25 | 'ST_ATIME': 7,
|
---|
26 | 'ST_MTIME': 8,
|
---|
27 | 'ST_CTIME': 9}
|
---|
28 |
|
---|
29 | # permission bit value are defined by POSIX
|
---|
30 | permission_bits = {
|
---|
31 | 'S_ISUID': 0o4000,
|
---|
32 | 'S_ISGID': 0o2000,
|
---|
33 | 'S_ENFMT': 0o2000,
|
---|
34 | 'S_ISVTX': 0o1000,
|
---|
35 | 'S_IRWXU': 0o700,
|
---|
36 | 'S_IRUSR': 0o400,
|
---|
37 | 'S_IREAD': 0o400,
|
---|
38 | 'S_IWUSR': 0o200,
|
---|
39 | 'S_IWRITE': 0o200,
|
---|
40 | 'S_IXUSR': 0o100,
|
---|
41 | 'S_IEXEC': 0o100,
|
---|
42 | 'S_IRWXG': 0o070,
|
---|
43 | 'S_IRGRP': 0o040,
|
---|
44 | 'S_IWGRP': 0o020,
|
---|
45 | 'S_IXGRP': 0o010,
|
---|
46 | 'S_IRWXO': 0o007,
|
---|
47 | 'S_IROTH': 0o004,
|
---|
48 | 'S_IWOTH': 0o002,
|
---|
49 | 'S_IXOTH': 0o001}
|
---|
50 |
|
---|
51 | def setUp(self):
|
---|
52 | try:
|
---|
53 | os.remove(TESTFN)
|
---|
54 | except OSError:
|
---|
55 | try:
|
---|
56 | os.rmdir(TESTFN)
|
---|
57 | except OSError:
|
---|
58 | pass
|
---|
59 | tearDown = setUp
|
---|
60 |
|
---|
61 | def get_mode(self, fname=TESTFN, lstat=True):
|
---|
62 | if lstat:
|
---|
63 | st_mode = os.lstat(fname).st_mode
|
---|
64 | else:
|
---|
65 | st_mode = os.stat(fname).st_mode
|
---|
66 | return st_mode
|
---|
67 |
|
---|
68 | def assertS_IS(self, name, mode):
|
---|
69 | # test format, lstrip is for S_IFIFO
|
---|
70 | fmt = getattr(stat, "S_IF" + name.lstrip("F"))
|
---|
71 | self.assertEqual(stat.S_IFMT(mode), fmt)
|
---|
72 | # test that just one function returns true
|
---|
73 | testname = "S_IS" + name
|
---|
74 | for funcname in self.format_funcs:
|
---|
75 | func = getattr(stat, funcname, None)
|
---|
76 | if func is None:
|
---|
77 | if funcname == testname:
|
---|
78 | raise ValueError(funcname)
|
---|
79 | continue
|
---|
80 | if funcname == testname:
|
---|
81 | self.assertTrue(func(mode))
|
---|
82 | else:
|
---|
83 | self.assertFalse(func(mode))
|
---|
84 |
|
---|
85 | def test_mode(self):
|
---|
86 | with open(TESTFN, 'w'):
|
---|
87 | pass
|
---|
88 | if os.name == 'posix':
|
---|
89 | os.chmod(TESTFN, 0o700)
|
---|
90 | st_mode = self.get_mode()
|
---|
91 | self.assertS_IS("REG", st_mode)
|
---|
92 | self.assertEqual(stat.S_IMODE(st_mode),
|
---|
93 | stat.S_IRWXU)
|
---|
94 |
|
---|
95 | os.chmod(TESTFN, 0o070)
|
---|
96 | st_mode = self.get_mode()
|
---|
97 | self.assertS_IS("REG", st_mode)
|
---|
98 | self.assertEqual(stat.S_IMODE(st_mode),
|
---|
99 | stat.S_IRWXG)
|
---|
100 |
|
---|
101 | os.chmod(TESTFN, 0o007)
|
---|
102 | st_mode = self.get_mode()
|
---|
103 | self.assertS_IS("REG", st_mode)
|
---|
104 | self.assertEqual(stat.S_IMODE(st_mode),
|
---|
105 | stat.S_IRWXO)
|
---|
106 |
|
---|
107 | os.chmod(TESTFN, 0o444)
|
---|
108 | st_mode = self.get_mode()
|
---|
109 | self.assertS_IS("REG", st_mode)
|
---|
110 | self.assertEqual(stat.S_IMODE(st_mode), 0o444)
|
---|
111 | else:
|
---|
112 | os.chmod(TESTFN, 0o700)
|
---|
113 | st_mode = self.get_mode()
|
---|
114 | self.assertS_IS("REG", st_mode)
|
---|
115 | self.assertEqual(stat.S_IFMT(st_mode),
|
---|
116 | stat.S_IFREG)
|
---|
117 |
|
---|
118 | def test_directory(self):
|
---|
119 | os.mkdir(TESTFN)
|
---|
120 | os.chmod(TESTFN, 0o700)
|
---|
121 | st_mode = self.get_mode()
|
---|
122 | self.assertS_IS("DIR", st_mode)
|
---|
123 |
|
---|
124 | @unittest.skipUnless(hasattr(os, 'symlink'), 'os.symlink not available')
|
---|
125 | def test_link(self):
|
---|
126 | try:
|
---|
127 | os.symlink(os.getcwd(), TESTFN)
|
---|
128 | except (OSError, NotImplementedError) as err:
|
---|
129 | raise unittest.SkipTest(str(err))
|
---|
130 | else:
|
---|
131 | st_mode = self.get_mode()
|
---|
132 | self.assertS_IS("LNK", st_mode)
|
---|
133 |
|
---|
134 | @unittest.skipUnless(hasattr(os, 'mkfifo'), 'os.mkfifo not available')
|
---|
135 | def test_fifo(self):
|
---|
136 | os.mkfifo(TESTFN, 0o700)
|
---|
137 | st_mode = self.get_mode()
|
---|
138 | self.assertS_IS("FIFO", st_mode)
|
---|
139 |
|
---|
140 | @unittest.skipUnless(os.name == 'posix', 'requires Posix')
|
---|
141 | def test_devices(self):
|
---|
142 | if os.path.exists(os.devnull):
|
---|
143 | st_mode = self.get_mode(os.devnull, lstat=False)
|
---|
144 | self.assertS_IS("CHR", st_mode)
|
---|
145 | # Linux block devices, BSD has no block devices anymore
|
---|
146 | for blockdev in ("/dev/sda", "/dev/hda"):
|
---|
147 | if os.path.exists(blockdev):
|
---|
148 | st_mode = self.get_mode(blockdev, lstat=False)
|
---|
149 | self.assertS_IS("BLK", st_mode)
|
---|
150 | break
|
---|
151 |
|
---|
152 | def test_module_attributes(self):
|
---|
153 | for key, value in self.stat_struct.items():
|
---|
154 | modvalue = getattr(stat, key)
|
---|
155 | self.assertEqual(value, modvalue, key)
|
---|
156 | for key, value in self.permission_bits.items():
|
---|
157 | modvalue = getattr(stat, key)
|
---|
158 | self.assertEqual(value, modvalue, key)
|
---|
159 | for key in self.file_flags:
|
---|
160 | modvalue = getattr(stat, key)
|
---|
161 | self.assertIsInstance(modvalue, int)
|
---|
162 | for key in self.formats:
|
---|
163 | modvalue = getattr(stat, key)
|
---|
164 | self.assertIsInstance(modvalue, int)
|
---|
165 | for key in self.format_funcs:
|
---|
166 | func = getattr(stat, key)
|
---|
167 | self.assertTrue(callable(func))
|
---|
168 | self.assertEqual(func(0), 0)
|
---|
169 |
|
---|
170 |
|
---|
171 | def test_main():
|
---|
172 | run_unittest(TestFilemode)
|
---|
173 |
|
---|
174 | if __name__ == '__main__':
|
---|
175 | test_main()
|
---|