123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- """Tests for scandir.walk(), copied from CPython's tests for os.walk()."""
- import os
- import shutil
- import sys
- import unittest
- import scandir
- import yatest.common
- walk_func = scandir.walk
- IS_PY3 = sys.version_info >= (3, 0)
- class TestWalk(unittest.TestCase):
- testfn = os.path.join(os.path.dirname(__file__), 'temp')
- def test_traversal(self):
- self.testfn = yatest.common.test_output_path('temp')
- # Build:
- # TESTFN/
- # TEST1/ a file kid and two directory kids
- # tmp1
- # SUB1/ a file kid and a directory kid
- # tmp2
- # SUB11/ no kids
- # SUB2/ a file kid and a dirsymlink kid
- # tmp3
- # link/ a symlink to TESTFN.2
- # TEST2/
- # tmp4 a lone file
- walk_path = os.path.join(self.testfn, "TEST1")
- sub1_path = os.path.join(walk_path, "SUB1")
- sub11_path = os.path.join(sub1_path, "SUB11")
- sub2_path = os.path.join(walk_path, "SUB2")
- tmp1_path = os.path.join(walk_path, "tmp1")
- tmp2_path = os.path.join(sub1_path, "tmp2")
- tmp3_path = os.path.join(sub2_path, "tmp3")
- link_path = os.path.join(sub2_path, "link")
- t2_path = os.path.join(self.testfn, "TEST2")
- tmp4_path = os.path.join(self.testfn, "TEST2", "tmp4")
- # Create stuff.
- os.makedirs(sub11_path)
- os.makedirs(sub2_path)
- os.makedirs(t2_path)
- for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path:
- f = open(path, "w")
- f.write("I'm " + path + " and proud of it. Blame test_os.\n")
- f.close()
- has_symlink = hasattr(os, "symlink")
- if has_symlink:
- try:
- if IS_PY3:
- os.symlink(os.path.abspath(t2_path), link_path, target_is_directory=True)
- else:
- os.symlink(os.path.abspath(t2_path), link_path)
- sub2_tree = (sub2_path, ["link"], ["tmp3"])
- except NotImplementedError:
- sub2_tree = (sub2_path, [], ["tmp3"])
- else:
- sub2_tree = (sub2_path, [], ["tmp3"])
- # Walk top-down.
- all = list(walk_func(walk_path))
- self.assertEqual(len(all), 4)
- # We can't know which order SUB1 and SUB2 will appear in.
- # Not flipped: TESTFN, SUB1, SUB11, SUB2
- # flipped: TESTFN, SUB2, SUB1, SUB11
- flipped = all[0][1][0] != "SUB1"
- all[0][1].sort()
- self.assertEqual(all[0], (walk_path, ["SUB1", "SUB2"], ["tmp1"]))
- self.assertEqual(all[1 + flipped], (sub1_path, ["SUB11"], ["tmp2"]))
- self.assertEqual(all[2 + flipped], (sub11_path, [], []))
- self.assertEqual(all[3 - 2 * flipped], sub2_tree)
- # Prune the search.
- all = []
- for root, dirs, files in walk_func(walk_path):
- all.append((root, dirs, files))
- # Don't descend into SUB1.
- if 'SUB1' in dirs:
- # Note that this also mutates the dirs we appended to all!
- dirs.remove('SUB1')
- self.assertEqual(len(all), 2)
- self.assertEqual(all[0], (walk_path, ["SUB2"], ["tmp1"]))
- self.assertEqual(all[1], sub2_tree)
- # Walk bottom-up.
- all = list(walk_func(walk_path, topdown=False))
- self.assertEqual(len(all), 4)
- # We can't know which order SUB1 and SUB2 will appear in.
- # Not flipped: SUB11, SUB1, SUB2, TESTFN
- # flipped: SUB2, SUB11, SUB1, TESTFN
- flipped = all[3][1][0] != "SUB1"
- all[3][1].sort()
- self.assertEqual(all[3], (walk_path, ["SUB1", "SUB2"], ["tmp1"]))
- self.assertEqual(all[flipped], (sub11_path, [], []))
- self.assertEqual(all[flipped + 1], (sub1_path, ["SUB11"], ["tmp2"]))
- self.assertEqual(all[2 - 2 * flipped], sub2_tree)
- if has_symlink:
- # Walk, following symlinks.
- for root, dirs, files in walk_func(walk_path, followlinks=True):
- if root == link_path:
- self.assertEqual(dirs, [])
- self.assertEqual(files, ["tmp4"])
- break
- else:
- self.fail("Didn't follow symlink with followlinks=True")
- # Test creating a directory and adding it to dirnames
- sub3_path = os.path.join(walk_path, "SUB3")
- all = []
- for root, dirs, files in walk_func(walk_path):
- all.append((root, dirs, files))
- if 'SUB1' in dirs:
- os.makedirs(sub3_path)
- dirs.append('SUB3')
- all.sort()
- self.assertEqual(os.path.split(all[-1][0])[1], 'SUB3')
- def tearDown(self):
- # Tear everything down. This is a decent use for bottom-up on
- # Windows, which doesn't have a recursive delete command. The
- # (not so) subtlety is that rmdir will fail unless the dir's
- # kids are removed first, so bottom up is essential.
- for root, dirs, files in os.walk(self.testfn, topdown=False):
- for name in files:
- os.remove(os.path.join(root, name))
- for name in dirs:
- dirname = os.path.join(root, name)
- if not os.path.islink(dirname):
- os.rmdir(dirname)
- else:
- os.remove(dirname)
- os.rmdir(self.testfn)
- class TestWalkSymlink(unittest.TestCase):
- temp_dir = os.path.join(os.path.dirname(__file__), 'temp')
- def setUp(self):
- self.temp_dir = yatest.common.test_output_path('temp')
- os.mkdir(self.temp_dir)
- self.dir_name = os.path.join(self.temp_dir, 'dir')
- os.mkdir(self.dir_name)
- open(os.path.join(self.dir_name, 'subfile'), 'w').close()
- self.file_name = os.path.join(self.temp_dir, 'file')
- open(self.file_name, 'w').close()
- def tearDown(self):
- shutil.rmtree(self.temp_dir)
- def test_symlink_to_file(self):
- if not hasattr(os, 'symlink'):
- return
- try:
- os.symlink(self.file_name, os.path.join(self.temp_dir,
- 'link_to_file'))
- except NotImplementedError:
- # Windows versions before Vista don't support symbolic links
- return
- output = sorted(walk_func(self.temp_dir))
- dirs = sorted(output[0][1])
- files = sorted(output[0][2])
- self.assertEqual(dirs, ['dir'])
- self.assertEqual(files, ['file', 'link_to_file'])
- self.assertEqual(len(output), 2)
- self.assertEqual(output[1][1], [])
- self.assertEqual(output[1][2], ['subfile'])
- def test_symlink_to_directory(self):
- if not hasattr(os, 'symlink'):
- return
- link_name = os.path.join(self.temp_dir, 'link_to_dir')
- try:
- if IS_PY3:
- os.symlink(self.dir_name, link_name, target_is_directory=True)
- else:
- os.symlink(self.dir_name, link_name)
- except NotImplementedError:
- # Windows versions before Vista don't support symbolic links
- return
- output = sorted(walk_func(self.temp_dir))
- dirs = sorted(output[0][1])
- files = sorted(output[0][2])
- self.assertEqual(dirs, ['dir', 'link_to_dir'])
- self.assertEqual(files, ['file'])
- self.assertEqual(len(output), 2)
- self.assertEqual(output[1][1], [])
- self.assertEqual(output[1][2], ['subfile'])
- output = sorted(walk_func(self.temp_dir, followlinks=True))
- dirs = sorted(output[0][1])
- files = sorted(output[0][2])
- self.assertEqual(dirs, ['dir', 'link_to_dir'])
- self.assertEqual(files, ['file'])
- self.assertEqual(len(output), 3)
- self.assertEqual(output[1][1], [])
- self.assertEqual(output[1][2], ['subfile'])
- self.assertEqual(os.path.basename(output[2][0]), 'link_to_dir')
- self.assertEqual(output[2][1], [])
- self.assertEqual(output[2][2], ['subfile'])
|