Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | # As a test suite for the os module, this is woefully inadequate, but this |
2 | # does add tests for a few functions which have been determined to be more | |
3 | # portable than they had been thought to be. | |
4 | ||
5 | import os | |
6 | import unittest | |
7 | import warnings | |
8 | from test import test_support | |
9 | ||
10 | warnings.filterwarnings("ignore", "tempnam", RuntimeWarning, __name__) | |
11 | warnings.filterwarnings("ignore", "tmpnam", RuntimeWarning, __name__) | |
12 | ||
13 | class TemporaryFileTests(unittest.TestCase): | |
14 | def setUp(self): | |
15 | self.files = [] | |
16 | os.mkdir(test_support.TESTFN) | |
17 | ||
18 | def tearDown(self): | |
19 | for name in self.files: | |
20 | os.unlink(name) | |
21 | os.rmdir(test_support.TESTFN) | |
22 | ||
23 | def check_tempfile(self, name): | |
24 | # make sure it doesn't already exist: | |
25 | self.failIf(os.path.exists(name), | |
26 | "file already exists for temporary file") | |
27 | # make sure we can create the file | |
28 | open(name, "w") | |
29 | self.files.append(name) | |
30 | ||
31 | def test_tempnam(self): | |
32 | if not hasattr(os, "tempnam"): | |
33 | return | |
34 | warnings.filterwarnings("ignore", "tempnam", RuntimeWarning, | |
35 | r"test_os$") | |
36 | self.check_tempfile(os.tempnam()) | |
37 | ||
38 | name = os.tempnam(test_support.TESTFN) | |
39 | self.check_tempfile(name) | |
40 | ||
41 | name = os.tempnam(test_support.TESTFN, "pfx") | |
42 | self.assert_(os.path.basename(name)[:3] == "pfx") | |
43 | self.check_tempfile(name) | |
44 | ||
45 | def test_tmpfile(self): | |
46 | if not hasattr(os, "tmpfile"): | |
47 | return | |
48 | fp = os.tmpfile() | |
49 | fp.write("foobar") | |
50 | fp.seek(0,0) | |
51 | s = fp.read() | |
52 | fp.close() | |
53 | self.assert_(s == "foobar") | |
54 | ||
55 | def test_tmpnam(self): | |
56 | import sys | |
57 | if not hasattr(os, "tmpnam"): | |
58 | return | |
59 | warnings.filterwarnings("ignore", "tmpnam", RuntimeWarning, | |
60 | r"test_os$") | |
61 | name = os.tmpnam() | |
62 | if sys.platform in ("win32",): | |
63 | # The Windows tmpnam() seems useless. From the MS docs: | |
64 | # | |
65 | # The character string that tmpnam creates consists of | |
66 | # the path prefix, defined by the entry P_tmpdir in the | |
67 | # file STDIO.H, followed by a sequence consisting of the | |
68 | # digit characters '0' through '9'; the numerical value | |
69 | # of this string is in the range 1 - 65,535. Changing the | |
70 | # definitions of L_tmpnam or P_tmpdir in STDIO.H does not | |
71 | # change the operation of tmpnam. | |
72 | # | |
73 | # The really bizarre part is that, at least under MSVC6, | |
74 | # P_tmpdir is "\\". That is, the path returned refers to | |
75 | # the root of the current drive. That's a terrible place to | |
76 | # put temp files, and, depending on privileges, the user | |
77 | # may not even be able to open a file in the root directory. | |
78 | self.failIf(os.path.exists(name), | |
79 | "file already exists for temporary file") | |
80 | else: | |
81 | self.check_tempfile(name) | |
82 | ||
83 | # Test attributes on return values from os.*stat* family. | |
84 | class StatAttributeTests(unittest.TestCase): | |
85 | def setUp(self): | |
86 | os.mkdir(test_support.TESTFN) | |
87 | self.fname = os.path.join(test_support.TESTFN, "f1") | |
88 | f = open(self.fname, 'wb') | |
89 | f.write("ABC") | |
90 | f.close() | |
91 | ||
92 | def tearDown(self): | |
93 | os.unlink(self.fname) | |
94 | os.rmdir(test_support.TESTFN) | |
95 | ||
96 | def test_stat_attributes(self): | |
97 | if not hasattr(os, "stat"): | |
98 | return | |
99 | ||
100 | import stat | |
101 | result = os.stat(self.fname) | |
102 | ||
103 | # Make sure direct access works | |
104 | self.assertEquals(result[stat.ST_SIZE], 3) | |
105 | self.assertEquals(result.st_size, 3) | |
106 | ||
107 | import sys | |
108 | ||
109 | # Make sure all the attributes are there | |
110 | members = dir(result) | |
111 | for name in dir(stat): | |
112 | if name[:3] == 'ST_': | |
113 | attr = name.lower() | |
114 | self.assertEquals(getattr(result, attr), | |
115 | result[getattr(stat, name)]) | |
116 | self.assert_(attr in members) | |
117 | ||
118 | try: | |
119 | result[200] | |
120 | self.fail("No exception thrown") | |
121 | except IndexError: | |
122 | pass | |
123 | ||
124 | # Make sure that assignment fails | |
125 | try: | |
126 | result.st_mode = 1 | |
127 | self.fail("No exception thrown") | |
128 | except TypeError: | |
129 | pass | |
130 | ||
131 | try: | |
132 | result.st_rdev = 1 | |
133 | self.fail("No exception thrown") | |
134 | except (AttributeError, TypeError): | |
135 | pass | |
136 | ||
137 | try: | |
138 | result.parrot = 1 | |
139 | self.fail("No exception thrown") | |
140 | except AttributeError: | |
141 | pass | |
142 | ||
143 | # Use the stat_result constructor with a too-short tuple. | |
144 | try: | |
145 | result2 = os.stat_result((10,)) | |
146 | self.fail("No exception thrown") | |
147 | except TypeError: | |
148 | pass | |
149 | ||
150 | # Use the constructr with a too-long tuple. | |
151 | try: | |
152 | result2 = os.stat_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)) | |
153 | except TypeError: | |
154 | pass | |
155 | ||
156 | ||
157 | def test_statvfs_attributes(self): | |
158 | if not hasattr(os, "statvfs"): | |
159 | return | |
160 | ||
161 | import statvfs | |
162 | try: | |
163 | result = os.statvfs(self.fname) | |
164 | except OSError, e: | |
165 | # On AtheOS, glibc always returns ENOSYS | |
166 | import errno | |
167 | if e.errno == errno.ENOSYS: | |
168 | return | |
169 | ||
170 | # Make sure direct access works | |
171 | self.assertEquals(result.f_bfree, result[statvfs.F_BFREE]) | |
172 | ||
173 | # Make sure all the attributes are there | |
174 | members = dir(result) | |
175 | for name in dir(statvfs): | |
176 | if name[:2] == 'F_': | |
177 | attr = name.lower() | |
178 | self.assertEquals(getattr(result, attr), | |
179 | result[getattr(statvfs, name)]) | |
180 | self.assert_(attr in members) | |
181 | ||
182 | # Make sure that assignment really fails | |
183 | try: | |
184 | result.f_bfree = 1 | |
185 | self.fail("No exception thrown") | |
186 | except TypeError: | |
187 | pass | |
188 | ||
189 | try: | |
190 | result.parrot = 1 | |
191 | self.fail("No exception thrown") | |
192 | except AttributeError: | |
193 | pass | |
194 | ||
195 | # Use the constructor with a too-short tuple. | |
196 | try: | |
197 | result2 = os.statvfs_result((10,)) | |
198 | self.fail("No exception thrown") | |
199 | except TypeError: | |
200 | pass | |
201 | ||
202 | # Use the constructr with a too-long tuple. | |
203 | try: | |
204 | result2 = os.statvfs_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)) | |
205 | except TypeError: | |
206 | pass | |
207 | ||
208 | from test import mapping_tests | |
209 | ||
210 | class EnvironTests(mapping_tests.BasicTestMappingProtocol): | |
211 | """check that os.environ object conform to mapping protocol""" | |
212 | type2test = None | |
213 | def _reference(self): | |
214 | return {"KEY1":"VALUE1", "KEY2":"VALUE2", "KEY3":"VALUE3"} | |
215 | def _empty_mapping(self): | |
216 | os.environ.clear() | |
217 | return os.environ | |
218 | def setUp(self): | |
219 | self.__save = dict(os.environ) | |
220 | os.environ.clear() | |
221 | def tearDown(self): | |
222 | os.environ.clear() | |
223 | os.environ.update(self.__save) | |
224 | ||
225 | class WalkTests(unittest.TestCase): | |
226 | """Tests for os.walk().""" | |
227 | ||
228 | def test_traversal(self): | |
229 | import os | |
230 | from os.path import join | |
231 | ||
232 | # Build: | |
233 | # TESTFN/ a file kid and two directory kids | |
234 | # tmp1 | |
235 | # SUB1/ a file kid and a directory kid | |
236 | # tmp2 | |
237 | # SUB11/ no kids | |
238 | # SUB2/ just a file kid | |
239 | # tmp3 | |
240 | sub1_path = join(test_support.TESTFN, "SUB1") | |
241 | sub11_path = join(sub1_path, "SUB11") | |
242 | sub2_path = join(test_support.TESTFN, "SUB2") | |
243 | tmp1_path = join(test_support.TESTFN, "tmp1") | |
244 | tmp2_path = join(sub1_path, "tmp2") | |
245 | tmp3_path = join(sub2_path, "tmp3") | |
246 | ||
247 | # Create stuff. | |
248 | os.makedirs(sub11_path) | |
249 | os.makedirs(sub2_path) | |
250 | for path in tmp1_path, tmp2_path, tmp3_path: | |
251 | f = file(path, "w") | |
252 | f.write("I'm " + path + " and proud of it. Blame test_os.\n") | |
253 | f.close() | |
254 | ||
255 | # Walk top-down. | |
256 | all = list(os.walk(test_support.TESTFN)) | |
257 | self.assertEqual(len(all), 4) | |
258 | # We can't know which order SUB1 and SUB2 will appear in. | |
259 | # Not flipped: TESTFN, SUB1, SUB11, SUB2 | |
260 | # flipped: TESTFN, SUB2, SUB1, SUB11 | |
261 | flipped = all[0][1][0] != "SUB1" | |
262 | all[0][1].sort() | |
263 | self.assertEqual(all[0], (test_support.TESTFN, ["SUB1", "SUB2"], ["tmp1"])) | |
264 | self.assertEqual(all[1 + flipped], (sub1_path, ["SUB11"], ["tmp2"])) | |
265 | self.assertEqual(all[2 + flipped], (sub11_path, [], [])) | |
266 | self.assertEqual(all[3 - 2 * flipped], (sub2_path, [], ["tmp3"])) | |
267 | ||
268 | # Prune the search. | |
269 | all = [] | |
270 | for root, dirs, files in os.walk(test_support.TESTFN): | |
271 | all.append((root, dirs, files)) | |
272 | # Don't descend into SUB1. | |
273 | if 'SUB1' in dirs: | |
274 | # Note that this also mutates the dirs we appended to all! | |
275 | dirs.remove('SUB1') | |
276 | self.assertEqual(len(all), 2) | |
277 | self.assertEqual(all[0], (test_support.TESTFN, ["SUB2"], ["tmp1"])) | |
278 | self.assertEqual(all[1], (sub2_path, [], ["tmp3"])) | |
279 | ||
280 | # Walk bottom-up. | |
281 | all = list(os.walk(test_support.TESTFN, topdown=False)) | |
282 | self.assertEqual(len(all), 4) | |
283 | # We can't know which order SUB1 and SUB2 will appear in. | |
284 | # Not flipped: SUB11, SUB1, SUB2, TESTFN | |
285 | # flipped: SUB2, SUB11, SUB1, TESTFN | |
286 | flipped = all[3][1][0] != "SUB1" | |
287 | all[3][1].sort() | |
288 | self.assertEqual(all[3], (test_support.TESTFN, ["SUB1", "SUB2"], ["tmp1"])) | |
289 | self.assertEqual(all[flipped], (sub11_path, [], [])) | |
290 | self.assertEqual(all[flipped + 1], (sub1_path, ["SUB11"], ["tmp2"])) | |
291 | self.assertEqual(all[2 - 2 * flipped], (sub2_path, [], ["tmp3"])) | |
292 | ||
293 | # Tear everything down. This is a decent use for bottom-up on | |
294 | # Windows, which doesn't have a recursive delete command. The | |
295 | # (not so) subtlety is that rmdir will fail unless the dir's | |
296 | # kids are removed first, so bottom up is essential. | |
297 | for root, dirs, files in os.walk(test_support.TESTFN, topdown=False): | |
298 | for name in files: | |
299 | os.remove(join(root, name)) | |
300 | for name in dirs: | |
301 | os.rmdir(join(root, name)) | |
302 | os.rmdir(test_support.TESTFN) | |
303 | ||
304 | class MakedirTests (unittest.TestCase): | |
305 | def setUp(self): | |
306 | os.mkdir(test_support.TESTFN) | |
307 | ||
308 | def test_makedir(self): | |
309 | base = test_support.TESTFN | |
310 | path = os.path.join(base, 'dir1', 'dir2', 'dir3') | |
311 | os.makedirs(path) # Should work | |
312 | path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4') | |
313 | os.makedirs(path) | |
314 | ||
315 | # Try paths with a '.' in them | |
316 | self.failUnlessRaises(OSError, os.makedirs, os.curdir) | |
317 | path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4', 'dir5', os.curdir) | |
318 | os.makedirs(path) | |
319 | path = os.path.join(base, 'dir1', os.curdir, 'dir2', 'dir3', 'dir4', | |
320 | 'dir5', 'dir6') | |
321 | os.makedirs(path) | |
322 | ||
323 | ||
324 | ||
325 | ||
326 | def tearDown(self): | |
327 | path = os.path.join(test_support.TESTFN, 'dir1', 'dir2', 'dir3', | |
328 | 'dir4', 'dir5', 'dir6') | |
329 | # If the tests failed, the bottom-most directory ('../dir6') | |
330 | # may not have been created, so we look for the outermost directory | |
331 | # that exists. | |
332 | while not os.path.exists(path) and path != test_support.TESTFN: | |
333 | path = os.path.dirname(path) | |
334 | ||
335 | os.removedirs(path) | |
336 | ||
337 | class DevNullTests (unittest.TestCase): | |
338 | def test_devnull(self): | |
339 | f = file(os.devnull, 'w') | |
340 | f.write('hello') | |
341 | f.close() | |
342 | f = file(os.devnull, 'r') | |
343 | self.assertEqual(f.read(), '') | |
344 | f.close() | |
345 | ||
346 | class URandomTests (unittest.TestCase): | |
347 | def test_urandom(self): | |
348 | try: | |
349 | self.assertEqual(len(os.urandom(1)), 1) | |
350 | self.assertEqual(len(os.urandom(10)), 10) | |
351 | self.assertEqual(len(os.urandom(100)), 100) | |
352 | self.assertEqual(len(os.urandom(1000)), 1000) | |
353 | except NotImplementedError: | |
354 | pass | |
355 | ||
356 | def test_main(): | |
357 | test_support.run_unittest( | |
358 | TemporaryFileTests, | |
359 | StatAttributeTests, | |
360 | EnvironTests, | |
361 | WalkTests, | |
362 | MakedirTests, | |
363 | DevNullTests, | |
364 | URandomTests | |
365 | ) | |
366 | ||
367 | if __name__ == "__main__": | |
368 | test_main() |