testing/mozbase/mozfile/tests/test_remove.py

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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))

mercurial