Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 #!/usr/bin/env python
3 import os
4 import stat
5 import shutil
6 import tempfile
7 import threading
8 import time
9 import unittest
11 import mozfile
12 import mozinfo
14 import stubs
17 def mark_readonly(path):
18 """Removes all write permissions from given file/directory.
20 :param path: path of directory/file of which modes must be changed
21 """
22 mode = os.stat(path)[stat.ST_MODE]
23 os.chmod(path, mode & ~stat.S_IWUSR & ~stat.S_IWGRP & ~stat.S_IWOTH)
26 class FileOpenCloseThread(threading.Thread):
27 """Helper thread for asynchronous file handling"""
28 def __init__(self, path, delay, delete=False):
29 threading.Thread.__init__(self)
30 self.delay = delay
31 self.path = path
32 self.delete = delete
34 def run(self):
35 with open(self.path) as f:
36 time.sleep(self.delay)
37 if self.delete:
38 try:
39 os.remove(self.path)
40 except:
41 pass
44 class MozfileRemoveTestCase(unittest.TestCase):
45 """Test our ability to remove directories and files"""
47 def setUp(self):
48 # Generate a stub
49 self.tempdir = stubs.create_stub()
51 def tearDown(self):
52 if os.path.isdir(self.tempdir):
53 shutil.rmtree(self.tempdir)
55 def test_remove_directory(self):
56 """Test the removal of a directory"""
57 self.assertTrue(os.path.isdir(self.tempdir))
58 mozfile.remove(self.tempdir)
59 self.assertFalse(os.path.exists(self.tempdir))
61 def test_remove_directory_with_open_file(self):
62 """Test removing a directory with an open file"""
63 # Open a file in the generated stub
64 filepath = os.path.join(self.tempdir, *stubs.files[1])
65 f = file(filepath, 'w')
66 f.write('foo-bar')
68 # keep file open and then try removing the dir-tree
69 if mozinfo.isWin:
70 # On the Windows family WindowsError should be raised.
71 self.assertRaises(OSError, mozfile.remove, self.tempdir)
72 self.assertTrue(os.path.exists(self.tempdir))
73 else:
74 # Folder should be deleted on all other platforms
75 mozfile.remove(self.tempdir)
76 self.assertFalse(os.path.exists(self.tempdir))
78 def test_remove_closed_file(self):
79 """Test removing a closed file"""
80 # Open a file in the generated stub
81 filepath = os.path.join(self.tempdir, *stubs.files[1])
82 with open(filepath, 'w') as f:
83 f.write('foo-bar')
85 # Folder should be deleted on all platforms
86 mozfile.remove(self.tempdir)
87 self.assertFalse(os.path.exists(self.tempdir))
89 def test_removing_open_file_with_retry(self):
90 """Test removing a file in use with retry"""
91 filepath = os.path.join(self.tempdir, *stubs.files[1])
93 thread = FileOpenCloseThread(filepath, 1)
94 thread.start()
96 # Wait a bit so we can be sure the file has been opened
97 time.sleep(.5)
98 mozfile.remove(filepath)
99 thread.join()
101 # Check deletion was successful
102 self.assertFalse(os.path.exists(filepath))
104 def test_removing_already_deleted_file_with_retry(self):
105 """Test removing a meanwhile removed file with retry"""
106 filepath = os.path.join(self.tempdir, *stubs.files[1])
108 thread = FileOpenCloseThread(filepath, .8, True)
109 thread.start()
111 # Wait a bit so we can be sure the file has been opened and gets deleted
112 # while remove() waits for the next retry
113 time.sleep(.5)
114 mozfile.remove(filepath)
115 thread.join()
117 # Check deletion was successful
118 self.assertFalse(os.path.exists(filepath))
120 def test_remove_readonly_tree(self):
121 """Test removing a read-only directory"""
123 dirpath = os.path.join(self.tempdir, "nested_tree")
124 mark_readonly(dirpath)
126 # However, mozfile should change write permissions and remove dir.
127 mozfile.remove(dirpath)
129 self.assertFalse(os.path.exists(dirpath))
131 def test_remove_readonly_file(self):
132 """Test removing read-only files"""
133 filepath = os.path.join(self.tempdir, *stubs.files[1])
134 mark_readonly(filepath)
136 # However, mozfile should change write permission and then remove file.
137 mozfile.remove(filepath)
139 self.assertFalse(os.path.exists(filepath))
141 @unittest.skipIf(mozinfo.isWin, "Symlinks are not supported on Windows")
142 def test_remove_symlink(self):
143 """Test removing a symlink"""
144 file_path = os.path.join(self.tempdir, *stubs.files[1])
145 symlink_path = os.path.join(self.tempdir, 'symlink')
147 os.symlink(file_path, symlink_path)
148 self.assertTrue(os.path.islink(symlink_path))
150 # The linked folder and files should not be deleted
151 mozfile.remove(symlink_path)
152 self.assertFalse(os.path.exists(symlink_path))
153 self.assertTrue(os.path.exists(file_path))
155 @unittest.skipIf(mozinfo.isWin, "Symlinks are not supported on Windows")
156 def test_remove_symlink_in_subfolder(self):
157 """Test removing a folder with an contained symlink"""
158 file_path = os.path.join(self.tempdir, *stubs.files[0])
159 dir_path = os.path.dirname(os.path.join(self.tempdir, *stubs.files[1]))
160 symlink_path = os.path.join(dir_path, 'symlink')
162 os.symlink(file_path, symlink_path)
163 self.assertTrue(os.path.islink(symlink_path))
165 # The folder with the contained symlink will be deleted but not the
166 # original linked file
167 mozfile.remove(dir_path)
168 self.assertFalse(os.path.exists(dir_path))
169 self.assertFalse(os.path.exists(symlink_path))
170 self.assertTrue(os.path.exists(file_path))
172 @unittest.skipIf(mozinfo.isWin or not os.geteuid(),
173 "Symlinks are not supported on Windows and cannot run test as root")
174 def test_remove_symlink_for_system_path(self):
175 """Test removing a symlink which points to a system folder"""
176 symlink_path = os.path.join(self.tempdir, 'symlink')
178 os.symlink(os.path.dirname(self.tempdir), symlink_path)
179 self.assertTrue(os.path.islink(symlink_path))
181 # The folder with the contained symlink will be deleted but not the
182 # original linked file
183 mozfile.remove(symlink_path)
184 self.assertFalse(os.path.exists(symlink_path))