Changeset 1838:41d9643b7ead


Ignore:
Timestamp:
Jul 11, 2019, 9:48:33 PM (3 months ago)
Author:
Stefan Schwarzer <sschwarzer@…>
Branch:
default
amend_source:
59191ee1e24dc67d06b667203fb21f4d001250f8
Message:
Use `ScriptedSession` in `TestLstatAndStat`
File:
1 edited

Legend:

Unmodified
Added
Removed
  • test/test_stat.py

    r1835 r1838  
    33# See the file LICENSE for licensing terms.
    44
     5import datetime
     6import ftplib
    57import stat
    68import time
     
    363365    """
    364366
    365     def setup_method(self, method):
    366         # Most tests in this class need the mock session class with
    367         # Unix format, so make this the default. Tests which need
    368         # the MS format can overwrite `self.stat` later.
    369         self.stat = \
    370           _test_stat(session_factory=mock_ftplib.MockUnixFormatSession)
    371 
    372367    def test_repr(self):
    373368        """Test if the `repr` result looks like a named tuple."""
    374         stat_result = self.stat._lstat("/home/sschwarzer/chemeng")
    375         # TODO: Make the value for `st_mtime` robust against DST "time
    376         # zone" changes.
    377         expected_result = (
    378           "StatResult(st_mode=17901, st_ino=None, st_dev=None, "
    379           "st_nlink=2, st_uid='45854', st_gid='200', st_size=512, "
    380           "st_atime=None, st_mtime=957391200.0, st_ctime=None)")
    381         assert repr(stat_result) == expected_result
     369        script = [
     370          Call("__init__"),
     371          Call("pwd", result="/"),
     372          Call("cwd", args=("/",)),
     373          Call("cwd", args=("/",)),
     374          Call("dir",
     375               args=("",),
     376               result="drwxr-sr-x   2 45854   200   512 May  4  2000 foo"),
     377          Call("cwd", args=("/",)),
     378          Call("close")
     379        ]
     380        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     381            host.stat_cache.disable()
     382            stat_result = host.stat("/foo")
     383            # TODO: Make the value for `st_mtime` robust against DST "time
     384            # zone" changes.
     385            expected_result = (
     386              "StatResult(st_mode=17901, st_ino=None, st_dev=None, "
     387              "st_nlink=2, st_uid='45854', st_gid='200', st_size=512, "
     388              "st_atime=None, st_mtime=957391200.0, st_ctime=None)")
     389            assert repr(stat_result) == expected_result
    382390
    383391    def test_failing_lstat(self):
    384392        """Test whether `lstat` fails for a nonexistent path."""
    385         with pytest.raises(ftputil.error.PermanentError):
    386             self.stat._lstat("/home/sschw/notthere")
    387         with pytest.raises(ftputil.error.PermanentError):
    388             self.stat._lstat("/home/sschwarzer/notthere")
     393        # Directory with presumed file item doesn't exist.
     394        script = [
     395          Call("__init__"),
     396          Call("pwd", result="/"),
     397          Call("cwd", args=("/",)),
     398          Call("cwd", args=("/",)),
     399          Call("dir", args=("",), result=""),
     400          Call("cwd", args=("/",)),
     401          # See FIXME comment in `ftputil.stat._Stat._real_lstat`
     402          Call("cwd", args=("/",)),
     403          Call("cwd", args=("/notthere",), result=ftplib.error_perm),
     404          Call("cwd", args=("/",)),
     405          Call("close")
     406        ]
     407        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     408            host.stat_cache.disable()
     409            with pytest.raises(ftputil.error.PermanentError):
     410                host.lstat("/notthere/irrelevant")
     411        # Directory exists, but not the file system item in the directory.
     412        script = [
     413          Call("__init__"),
     414          Call("pwd", result="/"),
     415          Call("cwd", args=("/",)),
     416          Call("cwd", args=("/",)),
     417          Call("dir",
     418               args=("",),
     419               result=test_base.dir_line(mode_string="dr-xr-xr-x",
     420                                         datetime_=datetime.datetime.now(),
     421                                         name="some_dir")),
     422          Call("cwd", args=("/",)),
     423          Call("cwd", args=("/",)),
     424          Call("cwd", args=("/some_dir",)),
     425          Call("dir", args=("",), result=""),
     426          Call("cwd", args=("/",)),
     427          Call("close")
     428        ]
     429        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     430            host.stat_cache.disable()
     431            with pytest.raises(ftputil.error.PermanentError):
     432                host.lstat("/some_dir/notthere")
    389433
    390434    def test_lstat_for_root(self):
     
    396440        possible to do this for the root directory `/`.
    397441        """
    398         with pytest.raises(ftputil.error.RootDirError) as exc_info:
    399             self.stat._lstat("/")
     442        script = [
     443          Call("__init__"),
     444          Call("pwd", result="/"),
     445          Call("close")
     446        ]
     447        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     448            host.stat_cache.disable()
     449            with pytest.raises(ftputil.error.RootDirError) as exc_info:
     450                host.lstat("/")
    400451        # `RootDirError` is "outside" the `FTPOSError` hierarchy.
    401452        assert not isinstance(exc_info.value, ftputil.error.FTPOSError)
     
    404455    def test_lstat_one_unix_file(self):
    405456        """Test `lstat` for a file described in Unix-style format."""
    406         stat_result = self.stat._lstat("/home/sschwarzer/index.html")
    407         # Second form is needed for Python 3
     457        script = [
     458          Call("__init__"),
     459          Call("pwd", result="/"),
     460          Call("cwd", args=("/",)),
     461          Call("cwd", args=("/",)),
     462          Call("dir",
     463               args=("",),
     464               result="-rw-r--r--   1 45854   200   4604 Jan 19 23:11 some_file"),
     465          Call("cwd", args=("/",)),
     466          Call("close")
     467        ]
     468        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     469            host.stat_cache.disable()
     470            stat_result = host.lstat("/some_file")
    408471        assert oct(stat_result.st_mode) == "0o100644"
    409472        assert stat_result.st_size == 4604
     
    412475    def test_lstat_one_ms_file(self):
    413476        """Test `lstat` for a file described in DOS-style format."""
    414         self.stat = _test_stat(session_factory=mock_ftplib.MockMSFormatSession)
    415         stat_result = self.stat._lstat("/home/msformat/abcd.exe")
     477        script = [
     478          Call("__init__"),
     479          Call("pwd", result="/"),
     480          Call("cwd", args=("/",)),
     481          Call("cwd", args=("/",)),
     482          # First try with unix parser, but this parser can't parse
     483          # this line.
     484          Call("dir",
     485               args=("",),
     486               result="07-17-00  02:08PM             12266720 some_file"),
     487          Call("cwd", args=("/",)),
     488          Call("cwd", args=("/",)),
     489          Call("cwd", args=("/",)),
     490          # Now try with MS parser.
     491          Call("dir",
     492               args=("",),
     493               result="07-17-00  02:08PM             12266720 some_file"),
     494          Call("cwd", args=("/",)),
     495          Call("close")
     496        ]
     497        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     498            host.stat_cache.disable()
     499            stat_result = host.lstat("/some_file")
     500        assert stat_result._st_name == "some_file"
    416501        assert stat_result._st_mtime_precision == 60
    417502
    418503    def test_lstat_one_unix_dir(self):
    419504        """Test `lstat` for a directory described in Unix-style format."""
    420         stat_result = self.stat._lstat("/home/sschwarzer/scios2")
    421         # Second form is needed for Python 3
     505        script = [
     506          Call("__init__"),
     507          Call("pwd", result="/"),
     508          Call("cwd", args=("/",)),
     509          Call("cwd", args=("/",)),
     510          Call("dir",
     511               args=("",),
     512               result="drwxr-sr-x   6 45854   200   512 Sep 20  1999 some_dir"),
     513          Call("cwd", args=("/",)),
     514          Call("close")
     515        ]
     516        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     517            host.stat_cache.disable()
     518            stat_result = host.lstat("/some_dir")
    422519        assert oct(stat_result.st_mode) == "0o42755"
    423520        assert stat_result.st_ino is None
     
    438535    def test_lstat_one_ms_dir(self):
    439536        """Test `lstat` for a directory described in DOS-style format."""
    440         self.stat = _test_stat(session_factory=mock_ftplib.MockMSFormatSession)
    441         stat_result = self.stat._lstat("/home/msformat/WindowsXP")
     537        script = [
     538          Call("__init__"),
     539          Call("pwd", result="/"),
     540          Call("cwd", args=("/",)),
     541          Call("cwd", args=("/",)),
     542          # First try with unix parser, but this parser can't parse
     543          # this line.
     544          Call("dir",
     545               args=("",),
     546               result="10-23-01  03:25PM       <DIR>          some_dir"),
     547          Call("cwd", args=("/",)),
     548          Call("cwd", args=("/",)),
     549          Call("cwd", args=("/",)),
     550          # Now try with MS parser.
     551          Call("dir",
     552               args=("",),
     553               result="10-23-01  03:25PM       <DIR>          some_dir"),
     554          Call("cwd", args=("/",)),
     555          Call("close")
     556        ]
     557        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     558            host.stat_cache.disable()
     559            stat_result = host.lstat("/some_dir")
    442560        assert stat_result._st_mtime_precision == 60
    443561
    444562    def test_lstat_via_stat_module(self):
    445563        """Test `lstat` indirectly via `stat` module."""
    446         stat_result = self.stat._lstat("/home/sschwarzer/")
     564        script = [
     565          Call("__init__"),
     566          Call("pwd", result="/"),
     567          Call("cwd", args=("/",)),
     568          Call("cwd", args=("/",)),
     569          Call("dir",
     570               args=("",),
     571               result="drwxr-sr-x   2 45854   200   512 May  4  2000 some_dir"),
     572          Call("cwd", args=("/",)),
     573          Call("close")
     574        ]
     575        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     576            host.stat_cache.disable()
     577            stat_result = host.lstat("/some_dir")
    447578        assert stat.S_ISDIR(stat_result.st_mode)
    448579
     
    450581        """Test `stat` when invoked on a link."""
    451582        # Simple link
    452         stat_result = self.stat._stat("/home/link")
     583        script = [
     584          Call("__init__"),
     585          Call("pwd", result="/"),
     586          Call("cwd", args=("/",)),
     587          Call("cwd", args=("/",)),
     588          Call("dir",
     589               args=("",),
     590               result="lrwxrwxrwx   1 45854   200   21 Jan 19  2002 link -> link_target"),
     591          Call("cwd", args=("/",)),
     592          Call("cwd", args=("/",)),
     593          Call("cwd", args=("/",)),
     594          Call("dir",
     595               args=("",),
     596               result="-rw-r--r--   1 45854   200   4604 Jan 19 23:11 link_target"),
     597          Call("cwd", args=("/",)),
     598          Call("close")
     599        ]
     600        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     601            host.stat_cache.disable()
     602            stat_result = host.stat("/link")
    453603        assert stat_result.st_size == 4604
    454604        # Link pointing to a link
    455         stat_result = self.stat._stat("/home/python/link_link")
     605        dir_lines = (
     606          "lrwxrwxrwx   1 45854   200   7    Jan 19  2002 link_link -> link\n"
     607          "lrwxrwxrwx   1 45854   200   14   Jan 19  2002 link -> link_target\n"
     608          "-rw-r--r--   1 45854   200   4604 Jan 19 23:11 link_target")
     609        # Note that only one `dir` call would be needed in case of an
     610        # enabled cache.
     611        script = [
     612          Call("__init__"),
     613          Call("pwd", result="/"),
     614          Call("cwd", args=("/",)),
     615          Call("cwd", args=("/",)),
     616          # Look up `/link_link`.
     617          Call("dir", args=("",), result=dir_lines),
     618          Call("cwd", args=("/",)),
     619          Call("cwd", args=("/",)),
     620          Call("cwd", args=("/",)),
     621          # Look up `/link`.
     622          Call("dir", args=("",), result=dir_lines),
     623          Call("cwd", args=("/",)),
     624          Call("cwd", args=("/",)),
     625          Call("cwd", args=("/",)),
     626          # Look up `/link_target`.
     627          Call("dir", args=("",), result=dir_lines),
     628          Call("cwd", args=("/",)),
     629          Call("close")
     630        ]
     631        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     632            host.stat_cache.disable()
     633            stat_result = host.stat("/link_link")
    456634        assert stat_result.st_size == 4604
    457         stat_result = self.stat._stat("../python/link_link")
    458         assert stat_result.st_size == 4604
    459         # Recursive link structures
    460         with pytest.raises(ftputil.error.PermanentError):
    461             self.stat._stat("../python/bad_link")
    462         with pytest.raises(ftputil.error.PermanentError):
    463             self.stat._stat("/home/bad_link")
     635        # Recursive link structure
     636        dir_lines = (
     637          "lrwxrwxrwx   1 45854   200   7    Jan 19  2002 bad_link1 -> bad_link2\n"
     638          "lrwxrwxrwx   1 45854   200   14   Jan 19  2002 bad_link2 -> bad_link1")
     639        script = [
     640          Call("__init__"),
     641          Call("pwd", result="/"),
     642          Call("cwd", args=("/",)),
     643          Call("cwd", args=("/",)),
     644          # This dir finds the `bad_link1` name requested in the `stat` call.
     645          Call("dir", args=("",), result=dir_lines),
     646          Call("cwd", args=("/",)),
     647          Call("cwd", args=("/",)),
     648          Call("cwd", args=("/",)),
     649          # Look up link target `bad_link2`.
     650          Call("dir", args=("",), result=dir_lines),
     651          Call("cwd", args=("/",)),
     652          Call("cwd", args=("/",)),
     653          Call("cwd", args=("/",)),
     654          # FIXME: `stat` looks up the link target pointed to by
     655          # `bad_link2`, which is `bad_link1`. Only here ftputil
     656          # notices the recursive link chain. Obviously the start of
     657          # the link chain hadn't been stored in `visited_paths` (see
     658          # also ticket #108).
     659          Call("dir", args=("",), result=dir_lines),
     660          Call("cwd", args=("/",)),
     661          Call("close")
     662        ]
     663        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     664            host.stat_cache.disable()
     665            with pytest.raises(ftputil.error.PermanentError):
     666                host.stat("bad_link1")
    464667
    465668    #
     
    468671    def test_parser_switching_with_permanent_error(self):
    469672        """Test non-switching of parser format with `PermanentError`."""
    470         self.stat = _test_stat(session_factory=mock_ftplib.MockMSFormatSession)
    471         assert self.stat._allow_parser_switching is True
    472         # With these directory contents, we get a `ParserError` for
    473         # the Unix parser first, so `_allow_parser_switching` can be
    474         # switched off no matter whether we got a `PermanentError`
    475         # afterward or not.
    476         with pytest.raises(ftputil.error.PermanentError):
    477             self.stat._lstat("/home/msformat/nonexistent")
    478         assert self.stat._allow_parser_switching is False
     673        script = [
     674          Call("__init__"),
     675          Call("pwd", result="/"),
     676          Call("cwd", args=("/",)),
     677          Call("cwd", args=("/",)),
     678          Call("dir",
     679               args=("",),
     680               result="10-23-01  03:25PM       <DIR>          home"),
     681          Call("cwd", args=("/",)),
     682          Call("cwd", args=("/",)),
     683          Call("cwd", args=("/",)),
     684          Call("dir",
     685               args=("",),
     686               result="10-23-01  03:25PM       <DIR>          home"),
     687          Call("cwd", args=("/",)),
     688          Call("close")
     689        ]
     690        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     691            host.stat_cache.disable()
     692            assert host._stat._allow_parser_switching is True
     693            # With these directory contents, we get a `ParserError` for
     694            # the Unix parser first, so `_allow_parser_switching` can be
     695            # switched off no matter whether we got a `PermanentError`
     696            # afterward or not.
     697            with pytest.raises(ftputil.error.PermanentError):
     698                host.lstat("/nonexistent")
     699            assert host._stat._allow_parser_switching is False
    479700
    480701    def test_parser_switching_default_to_unix(self):
    481702        """Test non-switching of parser format; stay with Unix."""
    482         assert self.stat._allow_parser_switching is True
    483         assert isinstance(self.stat._parser, ftputil.stat.UnixParser)
    484         stat_result = self.stat._lstat("/home/sschwarzer/index.html")
    485         # The Unix parser worked, so keep it.
    486         assert isinstance(self.stat._parser, ftputil.stat.UnixParser)
    487         assert self.stat._allow_parser_switching is False
     703        script = [
     704          Call("__init__"),
     705          Call("pwd", result="/"),
     706          Call("cwd", args=("/",)),
     707          Call("cwd", args=("/",)),
     708          Call("dir",
     709               args=("",),
     710               result="-rw-r--r--   1 45854   200   4604 Jan 19 23:11 some_file"),
     711          Call("cwd", args=("/",)),
     712          Call("close")
     713        ]
     714        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     715            host.stat_cache.disable()
     716            assert host._stat._allow_parser_switching is True
     717            assert host._stat._allow_parser_switching is True
     718            assert isinstance(host._stat._parser, ftputil.stat.UnixParser)
     719            stat_result = host.lstat("some_file")
     720            # The Unix parser worked, so keep it.
     721            assert isinstance(host._stat._parser, ftputil.stat.UnixParser)
     722            assert host._stat._allow_parser_switching is False
    488723
    489724    def test_parser_switching_to_ms(self):
    490725        """Test switching of parser from Unix to MS format."""
    491         self.stat = _test_stat(session_factory=mock_ftplib.MockMSFormatSession)
    492         assert self.stat._allow_parser_switching is True
    493         assert isinstance(self.stat._parser, ftputil.stat.UnixParser)
    494         # Parsing the directory `/home/msformat` with the Unix parser
    495         # fails, so switch to the MS parser.
    496         stat_result = self.stat._lstat("/home/msformat/abcd.exe")
    497         assert isinstance(self.stat._parser, ftputil.stat.MSParser)
    498         assert self.stat._allow_parser_switching is False
    499         assert stat_result._st_name == "abcd.exe"
    500         assert stat_result.st_size == 12266720
     726        script = [
     727          Call("__init__"),
     728          Call("pwd", result="/"),
     729          Call("cwd", args=("/",)),
     730          Call("cwd", args=("/",)),
     731          Call("dir",
     732               args=("",),
     733               result="07-17-00  02:08PM             12266720 some_file"),
     734          Call("cwd", args=("/",)),
     735          Call("cwd", args=("/",)),
     736          Call("cwd", args=("/",)),
     737          Call("dir",
     738               args=("",),
     739               result="07-17-00  02:08PM             12266720 some_file"),
     740          Call("cwd", args=("/",)),
     741          Call("close")
     742        ]
     743        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     744            host.stat_cache.disable()
     745            assert host._stat._allow_parser_switching is True
     746            assert isinstance(host._stat._parser, ftputil.stat.UnixParser)
     747            # Parsing the directory `/` with the Unix parser fails, so
     748            # switch to the MS parser.
     749            stat_result = host.lstat("/some_file")
     750            assert isinstance(host._stat._parser, ftputil.stat.MSParser)
     751            assert host._stat._allow_parser_switching is False
     752            assert stat_result._st_name == "some_file"
     753            assert stat_result.st_size == 12266720
    501754
    502755    def test_parser_switching_regarding_empty_dir(self):
    503756        """Test switching of parser if a directory is empty."""
    504         self.stat = _test_stat(session_factory=mock_ftplib.MockMSFormatSession)
    505         assert self.stat._allow_parser_switching is True
    506         # When the directory we're looking into doesn't give us any
    507         # lines we can't decide whether the first parser worked,
    508         # because it wasn't applied. So keep the parser for now.
    509         result = self.stat._listdir("/home/msformat/XPLaunch/empty")
    510         assert result == []
    511         assert self.stat._allow_parser_switching is True
    512         assert isinstance(self.stat._parser, ftputil.stat.UnixParser)
     757        script = [
     758          Call("__init__"),
     759          Call("pwd", result="/"),
     760          Call("cwd", args=("/",)),
     761          Call("cwd", args=("/",)),
     762          Call("dir", args=("",), result=""),
     763          Call("cwd", args=("/",)),
     764          Call("close")
     765        ]
     766        with test_base.ftp_host_factory(scripted_session.factory(script)) as host:
     767            host.stat_cache.disable()
     768            assert host._stat._allow_parser_switching is True
     769            # When the directory we're looking into doesn't give us any
     770            # lines we can't decide whether the first parser worked,
     771            # because it wasn't applied. So keep the parser for now.
     772            result = host.listdir("/")
     773            assert result == []
     774            assert host._stat._allow_parser_switching is True
     775            assert isinstance(host._stat._parser, ftputil.stat.UnixParser)
    513776
    514777
Note: See TracChangeset for help on using the changeset viewer.