diff options
| author | Prashanth Pai <ppai@redhat.com> | 2016-05-20 19:33:20 +0530 | 
|---|---|---|
| committer | Thiago da Silva <thiago@redhat.com> | 2016-11-18 08:15:52 -0800 | 
| commit | ce0feed60b2077085a66d34021a3c96bbb7f5558 (patch) | |
| tree | 59f2894f7555ae5e0881bdc17c33f7ea269df231 /test/unit/common | |
| parent | 2318a57a1ea632f77d5f78dc11023fb3b7fc2ad0 (diff) | |
Use scandir if available
scandir[1] is a directory iteration function like os.listdir(), which
can optimize os.walk() by avoiding unnecessary calls to os.stat()
Using scandir to avoid stat() calls requires GlusterFS to correctly
set d_type field of entries in readdir() responses[2].
[1] https://github.com/benhoyt/scandir
[2] http://review.gluster.org/#/c/14095/
Change-Id: Ibdb9a07d25708b5cd8fd663ac99669e7f1f7ba75
Signed-off-by: Prashanth Pai <ppai@redhat.com>
Reviewed-on: http://review.gluster.org/14460
Reviewed-by: Thiago da Silva <thiago@redhat.com>
Tested-by: Thiago da Silva <thiago@redhat.com>
Diffstat (limited to 'test/unit/common')
| -rw-r--r-- | test/unit/common/test_utils.py | 46 | 
1 files changed, 46 insertions, 0 deletions
diff --git a/test/unit/common/test_utils.py b/test/unit/common/test_utils.py index 8ba9a2a..4790304 100644 --- a/test/unit/common/test_utils.py +++ b/test/unit/common/test_utils.py @@ -34,6 +34,14 @@ from gluster.swift.common.exceptions import GlusterFileSystemOSError,\      GlusterFileSystemIOError  from swift.common.exceptions import DiskFileNoSpace +from nose import SkipTest + +try: +    import scandir +    scandir_present = True +except ImportError: +    scandir_present = False +  #  # Somewhat hacky way of emulating the operation of xattr calls. They are made  # against a dictionary that stores the xattr key/value pairs. @@ -1047,3 +1055,41 @@ class TestUtilsDirObjects(unittest.TestCase):                  self.fail("Expected OSError")          finally:              utils.do_rmdir = _orig_rm + +    def test_gf_listdir(self): +        for entry in utils.gf_listdir(self.rootdir): +            if scandir_present: +                self.assertFalse(isinstance(entry, utils.SmallDirEntry)) +            else: +                self.assertTrue(isinstance(entry, utils.SmallDirEntry)) +            if entry.name in ('dir1'): +                self.assertTrue(entry.is_dir()) +                if not scandir_present: +                    self.assertEqual(entry._d_type, utils.DT_UNKNOWN) +            elif entry.name in ('file1', 'file2'): +                self.assertFalse(entry.is_dir()) + + +class TestSmallDirEntry(unittest.TestCase): + +    def test_does_stat_when_no_d_type(self): +        e = utils.SmallDirEntry('/root/path', 'name', utils.DT_UNKNOWN) +        mock_os_lstat = Mock(return_value=Mock(st_mode=16744)) +        with patch('os.lstat', mock_os_lstat): +            self.assertTrue(e.is_dir()) +            self.assertTrue(e._stat)  # Make sure stat gets populated +        mock_os_lstat.assert_called_once_with('/root/path/name') + +        # Subsequent calls to is_dir() should not call os.lstat() +        mock_os_lstat.reset_mock() +        with patch('os.lstat', mock_os_lstat): +            self.assertTrue(e._stat)  # Make sure stat is already populated +            self.assertTrue(e.is_dir()) +        self.assertFalse(mock_os_lstat.called) + +    def test_is_dir_file_not_present_should_return_false(self): +        e = utils.SmallDirEntry('/root/path', 'name', utils.DT_UNKNOWN) +        mock_os_lstat = Mock(side_effect=OSError(errno.ENOENT, +                                                 os.strerror(errno.ENOENT))) +        with patch('os.lstat', mock_os_lstat): +            self.assertFalse(e.is_dir())  | 
