[elbe-devel] [PATCH 5/5] filesystem: Add dodctests
Torben Hohn
torben.hohn at linutronix.de
Mon May 25 15:24:30 CEST 2020
On Mon, May 18, 2020 at 10:10:00AM -0400, Olivier Dion wrote:
> Most of the tests are trivial and ensure that that all code paths are
> executed and proper exceptions are thrown.
>
> Some test are less easier to do. For example disk_usage(), which
> would requires to assume the size of small directories on a
> system.
>
> Also, to avoid clashing between files of different tests, each file
> created are prefix with the method tested.
>
> Signed-off-by: Olivier Dion <dion at linutronix.de>
> ---
> elbepack/filesystem.py | 172 +++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 172 insertions(+)
>
> diff --git a/elbepack/filesystem.py b/elbepack/filesystem.py
> index 99c5a013..09baf5ee 100644
> --- a/elbepack/filesystem.py
> +++ b/elbepack/filesystem.py
> @@ -56,6 +56,11 @@ class Filesystem(object):
> # pylint: disable=too-many-public-methods
>
> def __init__(self, path, clean=False):
> + """
> + >>> os.path.isdir(this.path)
> + True
> + """
> +
> self.path = os.path.abspath(path)
>
> if clean:
> @@ -63,39 +68,149 @@ class Filesystem(object):
> os.makedirs(self.path)
>
> def fname(self, path):
> + """
> + >>> this.fname('/fname')
> + '/tmp/elbe-doctests/fname'
> + """
mmm... i see, but this does not allow 2 elbe tests to run on the same
machine at once.
you can use
>>> this.fname('/fname') == os.path.join(this.path, '/fname')
True
and it seems like there are not so many occasions, where you rely on
/tmp/elbe-doctests
> if path.startswith('/'):
> path = path[1:]
> return os.path.join(self.path, path)
>
> def open(self, path, mode="r"):
> + """
> + >>> this.open("open") # doctest: +ELLIPSIS
> + Traceback (most recent call last):
> + ...
> + FileNotFoundError: [Errno 2] ...
> +
> + >>> this.open("open", mode="w") # doctest: +ELLIPSIS
> + <_io.TextIOWrapper ...>
> +
> + >>> _.close()
> + """
> return open(self.fname(path), mode)
>
> def open_gz(self, path, mode="r"):
> + """
> + >>> this.open_gz("open_gz") # doctest: +ELLIPSIS
> + Traceback (most recent call last):
> + ...
> + FileNotFoundError: [Errno 2] ...
> +
> + >>> this.open_gz("open_gz", mode="w") # doctest: +ELLIPSIS
> + <gzip _io.BufferedWriter ...>
> +
> + >>> _.close()
> + """
> return gzip.open(self.fname(path), mode)
>
> def isdir(self, path):
> + """
> + >>> this.isdir("isdir")
> + False
> +
> + >>> os.makedirs(this.fname("isdir"))
> + >>> this.isdir("isdir")
> + True
> + """
> return os.path.isdir(self.fname(path))
>
> def islink(self, path):
> + """
> + >>> this.islink("islink")
> + False
> +
> + >>> os.symlink("target", this.fname("islink"))
> + >>> this.islink("islink")
> + True
> + """
> return os.path.islink(self.fname(path))
>
> def isfile(self, path):
> + """
> + >>> this.isfile("isfile")
> + False
> +
> + >>> open(this.fname("isfile"), mode="w").close()
> + >>> this.isfile("isfile")
> + True
> + """
> return os.path.isfile(self.fname(path))
>
> def exists(self, path):
> + """
> + >>> this.exists("exists")
> + False
> +
> + >>> os.symlink("broken", this.fname("exixsts-broken-link"))
> + >>> this.exists("exists-broken-link")
> + False
> +
> + >>> open(this.fname("exists"), mode="w").close()
> + >>> this.exists("exists")
> + True
> + """
> return os.path.exists(self.fname(path))
>
> def lexists(self, path):
> + """
> + >>> this.lexists("lexists")
> + False
> +
> + >>> os.symlink("target", this.fname("lexists"))
> + >>> os.path.lexists(this.fname("lexists"))
> + True
> + """
> return os.path.lexists(self.fname(path))
>
> def mkdir(self, path):
> + """
> + >>> os.path.isdir(this.fname("mkdir"))
> + False
> + >>> this.mkdir("mkdir")
> + >>> os.path.isdir(this.fname("mkdir"))
> + True
> + """
> os.makedirs(self.realpath(path))
>
> def readlink(self, path):
> + """
> + >>> this.symlink("target", "readlink")
> + >>> this.readlink("readlink")
> + 'target'
> + """
> return os.readlink(self.fname(path))
>
> def realpath(self, path):
> + """
> + >>> this.realpath(".")
> + '/tmp/elbe-doctests'
> +
> + >>> this.realpath("..")
> + '/tmp/elbe-doctests'
> +
> + >>> this.realpath("/realpath")
> + '/tmp/elbe-doctests/realpath'
>
> + >>> this.symlink("/target", "realpath-abs-symlink")
> + >>> this.realpath("realpath-abs-symlink")
> + '/tmp/elbe-doctests/target'
> +
> + >>> this.symlink("target", "/realpath-symlink")
> + >>> this.realpath("realpath-symlink")
> + '/tmp/elbe-doctests/target'
> +
> + >>> this.symlink(".././realpath-symlink", "realpath-multi-symlink")
> + >>> this.realpath("realpath-multi-symlink")
> + '/tmp/elbe-doctests/target'
> +
> + >>> this.symlink("realpath-loop-A", "realpath-loop-B")
> + >>> this.symlink("realpath-loop-B", "realpath-loop-A")
> + >>> this.realpath("realpath-loop-A")
> + '/tmp/elbe-doctests/realpath-loop-A'
> + >>> this.realpath("realpath-loop-B")
> + '/tmp/elbe-doctests/realpath-loop-B'
> + """
ok... so here you also need to use the
>>> this.realpath("realpath-loop-B") == this.fname('/realpath-loop-B')
True
and then it will be fine.
> path = path.split(os.sep)
> path.reverse()
> following = []
> @@ -142,6 +257,23 @@ class Filesystem(object):
> return os.sep.join(real_path)
>
> def symlink(self, src, path, allow_exists=False):
> + """
> + >>> this.symlink("target", "symlink-link")
> + >>> os.readlink(this.fname("symlink-link"))
> + 'target'
> +
> + >>> this.symlink("target", "symlink-link") # doctest: +ELLIPSIS
> + Traceback (most recent call last):
> + ...
> + FileExistsError: [Errno 17] ...
> +
> + >>> os.readlink(this.fname("not-a-link")) # doctest: +ELLIPSIS
> + Traceback (most recent call last):
> + ...
> + FileNotFoundError: [Errno 2] ...
> +
> + >>> this.symlink("target", "symlink-link", allow_exists=True)
> + """
> try:
> os.symlink(src, self.fname(path))
> except OSError as e:
> @@ -173,6 +305,20 @@ class Filesystem(object):
> return content
>
> def remove(self, path, noerr=False):
> + """
> + >>> this.remove("remove") # doctest: +ELLIPSIS
> + Traceback (most recent call last):
> + ...
> + FileNotFoundError: [Errno 2] ...
> +
> + >>> this.remove("remove", noerr=True)
> +
> + >>> open(this.fname("remove"), "w").close()
> + >>> this.remove("remove")
> +
> + >>> this.lexists("remove")
> + False
> + """
> try:
> return os.remove(self.fname(path))
> except BaseException:
> @@ -180,6 +326,14 @@ class Filesystem(object):
> raise
>
> def rmtree(self, path):
> + """
> + >>> this.mkdir("/rmtree/rmtree")
> + >>> this.rmtree("/rmtree")
> + >>> this.lexists("/rmtree/rmtree")
> + False
> + >>> this.lexists("/rmtree")
> + False
> + """
> shutil.rmtree(self.fname(path))
>
> def listdir(self, path='', ignore=None, skiplinks=False):
> @@ -239,6 +393,24 @@ class Filesystem(object):
> - already exists, silently complete
> - regular file in the way, raise an exception
> - parent directory(ies) does not exist, make them as well
> +
> + --
> + >>> this.mkdir_p("mkdir_p/foo/bar")
> + >>> this.isdir("mkdir_p")
> + True
> +
> + >>> this.isdir("mkdir_p/foo")
> + True
> +
> + >>> this.isdir("mkdir_p/foo/bar")
> + True
> +
> + >>> open(this.fname("mkdir_p/foo/bar/baz"), "w").close()
> +
> + >>> this.mkdir_p("mkdir_p/foo/bar/baz") # doctest: +ELLIPSIS
> + Traceback (most recent call last):
> + ...
> + OSError: a file with the same name as the desired dir, ...
> """
> if self.isdir(newdir):
> pass
> --
> 2.26.2
>
>
> _______________________________________________
> elbe-devel mailing list
> elbe-devel at linutronix.de
> https://lists.linutronix.de/mailman/listinfo/elbe-devel
--
Torben Hohn
Linutronix GmbH | Bahnhofstrasse 3 | D-88690 Uhldingen-Mühlhofen
Phone: +49 7556 25 999 18; Fax.: +49 7556 25 999 99
Hinweise zum Datenschutz finden Sie hier (Informations on data privacy
can be found here): https://linutronix.de/kontakt/Datenschutz.php
Linutronix GmbH | Firmensitz (Registered Office): Uhldingen-Mühlhofen |
Registergericht (Registration Court): Amtsgericht Freiburg i.Br., HRB700
806 | Geschäftsführer (Managing Directors): Heinz Egger, Thomas Gleixner
More information about the elbe-devel
mailing list