Home | History | Annotate | Download | only in system
      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 FileSystemTest(unittest.TestCase):
     46     def setUp(self):
     47         self._this_dir = os.path.dirname(os.path.abspath(__file__))
     48         self._missing_file = os.path.join(self._this_dir, 'missing_file.py')
     49         self._this_file = os.path.join(self._this_dir, 'filesystem_unittest.py')
     50 
     51     def test_chdir(self):
     52         fs = FileSystem()
     53         cwd = fs.getcwd()
     54         newdir = '/'
     55         if sys.platform == 'win32':
     56             newdir = 'c:\\'
     57         fs.chdir(newdir)
     58         self.assertEquals(fs.getcwd(), newdir)
     59         fs.chdir(cwd)
     60 
     61     def test_chdir__notexists(self):
     62         fs = FileSystem()
     63         newdir = '/dirdoesnotexist'
     64         if sys.platform == 'win32':
     65             newdir = 'c:\\dirdoesnotexist'
     66         self.assertRaises(OSError, fs.chdir, newdir)
     67 
     68     def test_exists__true(self):
     69         fs = FileSystem()
     70         self.assertTrue(fs.exists(self._this_file))
     71 
     72     def test_exists__false(self):
     73         fs = FileSystem()
     74         self.assertFalse(fs.exists(self._missing_file))
     75 
     76     def test_getcwd(self):
     77         fs = FileSystem()
     78         self.assertTrue(fs.exists(fs.getcwd()))
     79 
     80     def test_isdir__true(self):
     81         fs = FileSystem()
     82         self.assertTrue(fs.isdir(self._this_dir))
     83 
     84     def test_isdir__false(self):
     85         fs = FileSystem()
     86         self.assertFalse(fs.isdir(self._this_file))
     87 
     88     def test_join(self):
     89         fs = FileSystem()
     90         self.assertEqual(fs.join('foo', 'bar'),
     91                          os.path.join('foo', 'bar'))
     92 
     93     def test_listdir(self):
     94         fs = FileSystem()
     95         with fs.mkdtemp(prefix='filesystem_unittest_') as d:
     96             self.assertEqual(fs.listdir(d), [])
     97             new_file = os.path.join(d, 'foo')
     98             fs.write_text_file(new_file, u'foo')
     99             self.assertEqual(fs.listdir(d), ['foo'])
    100             os.remove(new_file)
    101 
    102     def test_maybe_make_directory__success(self):
    103         fs = FileSystem()
    104 
    105         with fs.mkdtemp(prefix='filesystem_unittest_') as base_path:
    106             sub_path = os.path.join(base_path, "newdir")
    107             self.assertFalse(os.path.exists(sub_path))
    108             self.assertFalse(fs.isdir(sub_path))
    109 
    110             fs.maybe_make_directory(sub_path)
    111             self.assertTrue(os.path.exists(sub_path))
    112             self.assertTrue(fs.isdir(sub_path))
    113 
    114             # Make sure we can re-create it.
    115             fs.maybe_make_directory(sub_path)
    116             self.assertTrue(os.path.exists(sub_path))
    117             self.assertTrue(fs.isdir(sub_path))
    118 
    119             # Clean up.
    120             os.rmdir(sub_path)
    121 
    122         self.assertFalse(os.path.exists(base_path))
    123         self.assertFalse(fs.isdir(base_path))
    124 
    125     def test_maybe_make_directory__failure(self):
    126         # FIXME: os.chmod() doesn't work on Windows to set directories
    127         # as readonly, so we skip this test for now.
    128         if sys.platform in ('win32', 'cygwin'):
    129             return
    130 
    131         fs = FileSystem()
    132         with fs.mkdtemp(prefix='filesystem_unittest_') as d:
    133             # Remove write permissions on the parent directory.
    134             os.chmod(d, stat.S_IRUSR)
    135 
    136             # Now try to create a sub directory - should fail.
    137             sub_dir = fs.join(d, 'subdir')
    138             self.assertRaises(OSError, fs.maybe_make_directory, sub_dir)
    139 
    140             # Clean up in case the test failed and we did create the
    141             # directory.
    142             if os.path.exists(sub_dir):
    143                 os.rmdir(sub_dir)
    144 
    145     def test_read_and_write_file(self):
    146         fs = FileSystem()
    147         text_path = None
    148         binary_path = None
    149 
    150         unicode_text_string = u'ncde'
    151         hex_equivalent = '\xC5\xAA\x6E\xC4\xAD\x63\xC5\x8D\x64\x65\xCC\xBD'
    152         try:
    153             text_path = tempfile.mktemp(prefix='tree_unittest_')
    154             binary_path = tempfile.mktemp(prefix='tree_unittest_')
    155             fs.write_text_file(text_path, unicode_text_string)
    156             contents = fs.read_binary_file(text_path)
    157             self.assertEqual(contents, hex_equivalent)
    158 
    159             fs.write_text_file(binary_path, hex_equivalent)
    160             text_contents = fs.read_text_file(binary_path)
    161             self.assertEqual(text_contents, unicode_text_string)
    162         except:
    163             if text_path:
    164                 os.remove(text_path)
    165             if binary_path:
    166                 os.remove(binary_path)
    167 
    168     def test_read_binary_file__missing(self):
    169         fs = FileSystem()
    170         self.assertRaises(IOError, fs.read_binary_file, self._missing_file)
    171 
    172     def test_read_text_file__missing(self):
    173         fs = FileSystem()
    174         self.assertRaises(IOError, fs.read_text_file, self._missing_file)
    175 
    176     def test_remove_file_with_retry(self):
    177         FileSystemTest._remove_failures = 2
    178 
    179         def remove_with_exception(filename):
    180             FileSystemTest._remove_failures -= 1
    181             if FileSystemTest._remove_failures >= 0:
    182                 try:
    183                     raise WindowsError
    184                 except NameError:
    185                     raise FileSystem._WindowsError
    186 
    187         fs = FileSystem()
    188         self.assertTrue(fs.remove('filename', remove_with_exception))
    189         self.assertEquals(-1, FileSystemTest._remove_failures)
    190 
    191     def test_sep(self):
    192         fs = FileSystem()
    193 
    194         self.assertEquals(fs.sep, os.sep)
    195         self.assertEquals(fs.join("foo", "bar"),
    196                           os.path.join("foo", "bar"))
    197 
    198     def test_sep__is_readonly(self):
    199         def assign_sep():
    200             fs.sep = ' '
    201         fs = FileSystem()
    202         self.assertRaises(AttributeError, assign_sep)
    203 
    204 
    205 if __name__ == '__main__':
    206     unittest.main()
    207