initial import
[vuplus_webkit] / Tools / Scripts / webkitpy / common / system / filesystem_unittest.py
1 # vim: set fileencoding=utf-8 :
2 # Copyright (C) 2010 Google Inc. All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met:
7 #
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
13 # distribution.
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.
17 #
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.
29
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.
33
34 from __future__ import with_statement
35
36 import os
37 import stat
38 import sys
39 import tempfile
40 import unittest
41
42 from filesystem import FileSystem
43
44
45 class GenericFileSystemTests(object):
46     """Tests that should pass on either a real or mock filesystem."""
47     def setup_generic_test_dir(self):
48         fs = self.fs
49         self.generic_test_dir = str(self.fs.mkdtemp())
50         self.orig_cwd = fs.getcwd()
51         fs.chdir(self.generic_test_dir)
52         fs.write_text_file('foo.txt', 'foo')
53         fs.write_text_file('foobar', 'foobar')
54         fs.maybe_make_directory('foodir')
55         fs.write_text_file(fs.join('foodir', 'baz'), 'baz')
56         fs.chdir(self.orig_cwd)
57
58     def teardown_generic_test_dir(self):
59         self.fs.rmtree(self.generic_test_dir)
60         self.fs.chdir(self.orig_cwd)
61         self.generic_test_dir = None
62
63     def test_glob__trailing_asterisk(self):
64         self.fs.chdir(self.generic_test_dir)
65         self.assertEquals(set(self.fs.glob('fo*')), set(['foo.txt', 'foobar', 'foodir']))
66
67     def test_glob__leading_asterisk(self):
68         self.fs.chdir(self.generic_test_dir)
69         self.assertEquals(set(self.fs.glob('*xt')), set(['foo.txt']))
70
71     def test_glob__middle_asterisk(self):
72         self.fs.chdir(self.generic_test_dir)
73         self.assertEquals(set(self.fs.glob('f*r')), set(['foobar', 'foodir']))
74
75     def test_glob__period_is_escaped(self):
76         self.fs.chdir(self.generic_test_dir)
77         self.assertEquals(set(self.fs.glob('foo.*')), set(['foo.txt']))
78
79 class RealFileSystemTest(unittest.TestCase, GenericFileSystemTests):
80     def setUp(self):
81         self.fs = FileSystem()
82         self.setup_generic_test_dir()
83
84         self._this_dir = os.path.dirname(os.path.abspath(__file__))
85         self._missing_file = os.path.join(self._this_dir, 'missing_file.py')
86         self._this_file = os.path.join(self._this_dir, 'filesystem_unittest.py')
87
88     def tearDown(self):
89         self.teardown_generic_test_dir()
90         self.fs = None
91
92     def test_chdir(self):
93         fs = FileSystem()
94         cwd = fs.getcwd()
95         newdir = '/'
96         if sys.platform == 'win32':
97             newdir = 'c:\\'
98         fs.chdir(newdir)
99         self.assertEquals(fs.getcwd(), newdir)
100         fs.chdir(cwd)
101
102     def test_chdir__notexists(self):
103         fs = FileSystem()
104         newdir = '/dirdoesnotexist'
105         if sys.platform == 'win32':
106             newdir = 'c:\\dirdoesnotexist'
107         self.assertRaises(OSError, fs.chdir, newdir)
108
109     def test_exists__true(self):
110         fs = FileSystem()
111         self.assertTrue(fs.exists(self._this_file))
112
113     def test_exists__false(self):
114         fs = FileSystem()
115         self.assertFalse(fs.exists(self._missing_file))
116
117     def test_getcwd(self):
118         fs = FileSystem()
119         self.assertTrue(fs.exists(fs.getcwd()))
120
121     def test_isdir__true(self):
122         fs = FileSystem()
123         self.assertTrue(fs.isdir(self._this_dir))
124
125     def test_isdir__false(self):
126         fs = FileSystem()
127         self.assertFalse(fs.isdir(self._this_file))
128
129     def test_join(self):
130         fs = FileSystem()
131         self.assertEqual(fs.join('foo', 'bar'),
132                          os.path.join('foo', 'bar'))
133
134     def test_listdir(self):
135         fs = FileSystem()
136         with fs.mkdtemp(prefix='filesystem_unittest_') as d:
137             self.assertEqual(fs.listdir(d), [])
138             new_file = os.path.join(d, 'foo')
139             fs.write_text_file(new_file, u'foo')
140             self.assertEqual(fs.listdir(d), ['foo'])
141             os.remove(new_file)
142
143     def test_maybe_make_directory__success(self):
144         fs = FileSystem()
145
146         with fs.mkdtemp(prefix='filesystem_unittest_') as base_path:
147             sub_path = os.path.join(base_path, "newdir")
148             self.assertFalse(os.path.exists(sub_path))
149             self.assertFalse(fs.isdir(sub_path))
150
151             fs.maybe_make_directory(sub_path)
152             self.assertTrue(os.path.exists(sub_path))
153             self.assertTrue(fs.isdir(sub_path))
154
155             # Make sure we can re-create it.
156             fs.maybe_make_directory(sub_path)
157             self.assertTrue(os.path.exists(sub_path))
158             self.assertTrue(fs.isdir(sub_path))
159
160             # Clean up.
161             os.rmdir(sub_path)
162
163         self.assertFalse(os.path.exists(base_path))
164         self.assertFalse(fs.isdir(base_path))
165
166     def test_maybe_make_directory__failure(self):
167         # FIXME: os.chmod() doesn't work on Windows to set directories
168         # as readonly, so we skip this test for now.
169         if sys.platform in ('win32', 'cygwin'):
170             return
171
172         fs = FileSystem()
173         with fs.mkdtemp(prefix='filesystem_unittest_') as d:
174             # Remove write permissions on the parent directory.
175             os.chmod(d, stat.S_IRUSR)
176
177             # Now try to create a sub directory - should fail.
178             sub_dir = fs.join(d, 'subdir')
179             self.assertRaises(OSError, fs.maybe_make_directory, sub_dir)
180
181             # Clean up in case the test failed and we did create the
182             # directory.
183             if os.path.exists(sub_dir):
184                 os.rmdir(sub_dir)
185
186     def test_read_and_write_text_file(self):
187         fs = FileSystem()
188         text_path = None
189
190         unicode_text_string = u'\u016An\u012Dc\u014Dde\u033D'
191         hex_equivalent = '\xC5\xAA\x6E\xC4\xAD\x63\xC5\x8D\x64\x65\xCC\xBD'
192         try:
193             text_path = tempfile.mktemp(prefix='tree_unittest_')
194             file = fs.open_text_file_for_writing(text_path)
195             file.write(unicode_text_string)
196             file.close()
197
198             file = fs.open_text_file_for_reading(text_path)
199             read_text = file.read()
200             file.close()
201
202             self.assertEqual(read_text, unicode_text_string)
203         finally:
204             if text_path and fs.isfile(text_path):
205                 os.remove(text_path)
206
207     def test_read_and_write_file(self):
208         fs = FileSystem()
209         text_path = None
210         binary_path = None
211
212         unicode_text_string = u'\u016An\u012Dc\u014Dde\u033D'
213         hex_equivalent = '\xC5\xAA\x6E\xC4\xAD\x63\xC5\x8D\x64\x65\xCC\xBD'
214         try:
215             text_path = tempfile.mktemp(prefix='tree_unittest_')
216             binary_path = tempfile.mktemp(prefix='tree_unittest_')
217             fs.write_text_file(text_path, unicode_text_string)
218             contents = fs.read_binary_file(text_path)
219             self.assertEqual(contents, hex_equivalent)
220
221             fs.write_binary_file(binary_path, hex_equivalent)
222             text_contents = fs.read_text_file(binary_path)
223             self.assertEqual(text_contents, unicode_text_string)
224         finally:
225             if text_path and fs.isfile(text_path):
226                 os.remove(text_path)
227             if binary_path and fs.isfile(binary_path):
228                 os.remove(binary_path)
229
230     def test_read_binary_file__missing(self):
231         fs = FileSystem()
232         self.assertRaises(IOError, fs.read_binary_file, self._missing_file)
233
234     def test_read_text_file__missing(self):
235         fs = FileSystem()
236         self.assertRaises(IOError, fs.read_text_file, self._missing_file)
237
238     def test_remove_file_with_retry(self):
239         RealFileSystemTest._remove_failures = 2
240
241         def remove_with_exception(filename):
242             RealFileSystemTest._remove_failures -= 1
243             if RealFileSystemTest._remove_failures >= 0:
244                 try:
245                     raise WindowsError
246                 except NameError:
247                     raise FileSystem._WindowsError
248
249         fs = FileSystem()
250         self.assertTrue(fs.remove('filename', remove_with_exception))
251         self.assertEquals(-1, RealFileSystemTest._remove_failures)
252
253     def test_sep(self):
254         fs = FileSystem()
255
256         self.assertEquals(fs.sep, os.sep)
257         self.assertEquals(fs.join("foo", "bar"),
258                           os.path.join("foo", "bar"))
259
260     def test_sep__is_readonly(self):
261         def assign_sep():
262             fs.sep = ' '
263         fs = FileSystem()
264         self.assertRaises(AttributeError, assign_sep)
265
266 if __name__ == '__main__':
267     unittest.main()