1 # vim: set fileencoding=utf-8 :
2 # Copyright (C) 2010 Google Inc. All rights reserved.
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following disclaimer
12 # in the documentation and/or other materials provided with the
14 # * Neither the name of Google Inc. nor the names of its
15 # contributors may be used to endorse or promote products derived from
16 # this software without specific prior written permission.
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 # NOTE: The fileencoding comment on the first line of the file is
31 # important; without it, Python will choke while trying to parse the file,
32 # since it includes non-ASCII characters.
40 from webkitpy.common.system.filesystem import FileSystem
43 class GenericFileSystemTests(object):
44 """Tests that should pass on either a real or mock filesystem."""
45 # pylint gets confused about this being a mixin: pylint: disable=E1101
46 def setup_generic_test_dir(self):
48 self.generic_test_dir = str(self.fs.mkdtemp())
49 self.orig_cwd = fs.getcwd()
50 fs.chdir(self.generic_test_dir)
51 fs.write_text_file('foo.txt', 'foo')
52 fs.write_text_file('foobar', 'foobar')
53 fs.maybe_make_directory('foodir')
54 fs.write_text_file(fs.join('foodir', 'baz'), 'baz')
55 fs.chdir(self.orig_cwd)
57 def teardown_generic_test_dir(self):
58 self.fs.rmtree(self.generic_test_dir)
59 self.fs.chdir(self.orig_cwd)
60 self.generic_test_dir = None
62 def test_glob__trailing_asterisk(self):
63 self.fs.chdir(self.generic_test_dir)
64 self.assertEqual(set(self.fs.glob('fo*')), set(['foo.txt', 'foobar', 'foodir']))
66 def test_glob__leading_asterisk(self):
67 self.fs.chdir(self.generic_test_dir)
68 self.assertEqual(set(self.fs.glob('*xt')), set(['foo.txt']))
70 def test_glob__middle_asterisk(self):
71 self.fs.chdir(self.generic_test_dir)
72 self.assertEqual(set(self.fs.glob('f*r')), set(['foobar', 'foodir']))
74 def test_glob__period_is_escaped(self):
75 self.fs.chdir(self.generic_test_dir)
76 self.assertEqual(set(self.fs.glob('foo.*')), set(['foo.txt']))
78 def test_relpath_unix(self):
79 if sys.platform == 'win32':
81 self.assertEqual(self.fs.relpath('aaa/bbb'), 'aaa/bbb')
82 self.assertEqual(self.fs.relpath('aaa/bbb/'), 'aaa/bbb')
83 self.assertEqual(self.fs.relpath('aaa/bbb/.'), 'aaa/bbb')
84 self.assertEqual(self.fs.relpath('aaa/./bbb'), 'aaa/bbb')
85 self.assertEqual(self.fs.relpath('aaa/../bbb/'), 'bbb')
86 self.assertEqual(self.fs.relpath('aaa/bbb', 'aaa/bbb'), '.')
87 self.assertEqual(self.fs.relpath('aaa/bbb/ccc', 'aaa/bbb'), 'ccc')
88 self.assertEqual(self.fs.relpath('aaa/./ccc', 'aaa/bbb'), '../ccc')
89 self.assertEqual(self.fs.relpath('aaa/../ccc', 'aaa/bbb'), '../../ccc')
90 self.assertEqual(self.fs.relpath('aaa/bbb', 'aaa/ccc'), '../bbb')
91 self.assertEqual(self.fs.relpath('aaa/bbb', 'ccc/ddd'), '../../aaa/bbb')
92 self.assertEqual(self.fs.relpath('aaa/bbb', 'aaa/b'), '../bbb')
93 self.assertEqual(self.fs.relpath('aaa/bbb', 'a/bbb'), '../../aaa/bbb')
95 def test_relpath_win32(self):
96 if sys.platform != 'win32':
98 self.assertEqual(self.fs.relpath('aaa\\bbb'), 'aaa\\bbb')
99 self.assertEqual(self.fs.relpath('aaa\\bbb\\'), 'aaa\\bbb')
100 self.assertEqual(self.fs.relpath('aaa\\bbb\\.'), 'aaa\\bbb')
101 self.assertEqual(self.fs.relpath('aaa\\.\\bbb'), 'aaa\\bbb')
102 self.assertEqual(self.fs.relpath('aaa\\..\\bbb\\'), 'bbb')
103 self.assertEqual(self.fs.relpath('aaa\\bbb', 'aaa\\bbb'), '.')
104 self.assertEqual(self.fs.relpath('aaa\\bbb\\ccc', 'aaa\\bbb'), 'ccc')
105 self.assertEqual(self.fs.relpath('aaa\\.\\ccc', 'aaa\\bbb'), '..\\ccc')
106 self.assertEqual(self.fs.relpath('aaa\\..\\ccc', 'aaa\\bbb'), '..\\..\\ccc')
107 self.assertEqual(self.fs.relpath('aaa\\bbb', 'aaa\\ccc'), '..\\bbb')
108 self.assertEqual(self.fs.relpath('aaa\\bbb', 'ccc\\ddd'), '..\\..\\aaa\\bbb')
109 self.assertEqual(self.fs.relpath('aaa\\bbb', 'aaa\\b'), '..\\bbb')
110 self.assertEqual(self.fs.relpath('aaa\\bbb', 'a\\bbb'), '..\\..\\aaa\\bbb')
112 def test_rmtree(self):
113 self.fs.chdir(self.generic_test_dir)
114 self.fs.rmtree('foo')
115 self.assertTrue(self.fs.exists('foodir'))
116 self.assertTrue(self.fs.exists(self.fs.join('foodir', 'baz')))
117 self.fs.rmtree('foodir')
118 self.assertFalse(self.fs.exists('foodir'))
119 self.assertFalse(self.fs.exists(self.fs.join('foodir', 'baz')))
121 def test_copytree(self):
122 self.fs.chdir(self.generic_test_dir)
123 self.fs.copytree('foodir/', 'bardir/')
124 self.assertTrue(self.fs.exists('bardir'))
125 self.assertTrue(self.fs.exists(self.fs.join('bardir', 'baz')))
128 self.fs.chdir(self.generic_test_dir)
129 self.fs.move('foo.txt', 'bar.txt')
130 self.assertFalse(self.fs.exists('foo.txt'))
131 self.assertTrue(self.fs.exists('bar.txt'))
132 self.fs.move('foodir', 'bardir')
133 self.assertFalse(self.fs.exists('foodir'))
134 self.assertFalse(self.fs.exists(self.fs.join('foodir', 'baz')))
135 self.assertTrue(self.fs.exists('bardir'))
136 self.assertTrue(self.fs.exists(self.fs.join('bardir', 'baz')))
138 class RealFileSystemTest(unittest.TestCase, GenericFileSystemTests):
140 self.fs = FileSystem()
141 self.setup_generic_test_dir()
143 self._this_dir = os.path.dirname(os.path.abspath(__file__))
144 self._missing_file = os.path.join(self._this_dir, 'missing_file.py')
145 self._this_file = os.path.join(self._this_dir, 'filesystem_unittest.py')
148 self.teardown_generic_test_dir()
151 def test_chdir(self):
155 if sys.platform == 'win32':
158 self.assertEqual(fs.getcwd(), newdir)
161 def test_chdir__notexists(self):
163 newdir = '/dirdoesnotexist'
164 if sys.platform == 'win32':
165 newdir = 'c:\\dirdoesnotexist'
166 self.assertRaises(OSError, fs.chdir, newdir)
168 def test_exists__true(self):
170 self.assertTrue(fs.exists(self._this_file))
172 def test_exists__false(self):
174 self.assertFalse(fs.exists(self._missing_file))
176 def test_getcwd(self):
178 self.assertTrue(fs.exists(fs.getcwd()))
180 def test_isdir__true(self):
182 self.assertTrue(fs.isdir(self._this_dir))
184 def test_isdir__false(self):
186 self.assertFalse(fs.isdir(self._this_file))
190 self.assertEqual(fs.join('foo', 'bar'),
191 os.path.join('foo', 'bar'))
193 def test_listdir(self):
195 with fs.mkdtemp(prefix='filesystem_unittest_') as d:
196 self.assertEqual(fs.listdir(d), [])
197 new_file = os.path.join(d, 'foo')
198 fs.write_text_file(new_file, u'foo')
199 self.assertEqual(fs.listdir(d), ['foo'])
204 with fs.mkdtemp(prefix='filesystem_unittest_') as d:
205 self.assertEqual(list(fs.walk(d)), [(d, [], [])])
206 new_file = os.path.join(d, 'foo')
207 fs.write_text_file(new_file, u'foo')
208 self.assertEqual(list(fs.walk(d)), [(d, [], ['foo'])])
211 def test_maybe_make_directory__success(self):
214 with fs.mkdtemp(prefix='filesystem_unittest_') as base_path:
215 sub_path = os.path.join(base_path, "newdir")
216 self.assertFalse(os.path.exists(sub_path))
217 self.assertFalse(fs.isdir(sub_path))
219 fs.maybe_make_directory(sub_path)
220 self.assertTrue(os.path.exists(sub_path))
221 self.assertTrue(fs.isdir(sub_path))
223 # Make sure we can re-create it.
224 fs.maybe_make_directory(sub_path)
225 self.assertTrue(os.path.exists(sub_path))
226 self.assertTrue(fs.isdir(sub_path))
231 self.assertFalse(os.path.exists(base_path))
232 self.assertFalse(fs.isdir(base_path))
234 def test_maybe_make_directory__failure(self):
235 # FIXME: os.chmod() doesn't work on Windows to set directories
236 # as readonly, so we skip this test for now.
237 if sys.platform in ('win32', 'cygwin'):
241 with fs.mkdtemp(prefix='filesystem_unittest_') as d:
242 # Remove write permissions on the parent directory.
243 os.chmod(d, stat.S_IRUSR)
245 # Now try to create a sub directory - should fail.
246 sub_dir = fs.join(d, 'subdir')
247 self.assertRaises(OSError, fs.maybe_make_directory, sub_dir)
249 # Clean up in case the test failed and we did create the
251 if os.path.exists(sub_dir):
254 def test_read_and_write_text_file(self):
258 unicode_text_string = u'\u016An\u012Dc\u014Dde\u033D'
259 hex_equivalent = '\xC5\xAA\x6E\xC4\xAD\x63\xC5\x8D\x64\x65\xCC\xBD'
261 text_path = tempfile.mktemp(prefix='tree_unittest_')
262 file = fs.open_text_file_for_writing(text_path)
263 file.write(unicode_text_string)
266 file = fs.open_text_file_for_reading(text_path)
267 read_text = file.read()
270 self.assertEqual(read_text, unicode_text_string)
272 if text_path and fs.isfile(text_path):
275 def test_read_and_write_file(self):
280 unicode_text_string = u'\u016An\u012Dc\u014Dde\u033D'
281 hex_equivalent = '\xC5\xAA\x6E\xC4\xAD\x63\xC5\x8D\x64\x65\xCC\xBD'
283 text_path = tempfile.mktemp(prefix='tree_unittest_')
284 binary_path = tempfile.mktemp(prefix='tree_unittest_')
285 fs.write_text_file(text_path, unicode_text_string)
286 contents = fs.read_binary_file(text_path)
287 self.assertEqual(contents, hex_equivalent)
289 fs.write_binary_file(binary_path, hex_equivalent)
290 text_contents = fs.read_text_file(binary_path)
291 self.assertEqual(text_contents, unicode_text_string)
293 if text_path and fs.isfile(text_path):
295 if binary_path and fs.isfile(binary_path):
296 os.remove(binary_path)
298 def test_read_binary_file__missing(self):
300 self.assertRaises(IOError, fs.read_binary_file, self._missing_file)
302 def test_read_text_file__missing(self):
304 self.assertRaises(IOError, fs.read_text_file, self._missing_file)
306 def test_remove_file_with_retry(self):
307 RealFileSystemTest._remove_failures = 2
309 def remove_with_exception(filename):
310 RealFileSystemTest._remove_failures -= 1
311 if RealFileSystemTest._remove_failures >= 0:
315 raise FileSystem._WindowsError
318 self.assertTrue(fs.remove('filename', remove_with_exception))
319 self.assertEqual(-1, RealFileSystemTest._remove_failures)
324 self.assertEqual(fs.sep, os.sep)
325 self.assertEqual(fs.join("foo", "bar"),
326 os.path.join("foo", "bar"))