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