[elbe-devel] [PATCH v2 3/6] shellhelper: Add doctests

Torben Hohn torben.hohn at linutronix.de
Wed Jun 3 10:55:28 CEST 2020


On Mon, May 25, 2020 at 02:25:53PM -0400, Olivier Dion wrote:
> Tests were made in order to execute all code paths and to keep stdout
> clean.  Thus, nothing is ever printed to the terminal.
> 
> The tests for do(), chroot() and get_command_out() require to
> manipulate the loggers of the Python's logging module.
> 
> Signed-off-by: Olivier Dion <dion at linutronix.de>

ok. i am iritated, that you did not need to add any code
to the logging module.

But this looks easy enough, and couldnt be made easier,
with an additional function.

Reviewed-by: Torben Hohn <torben.hohn at linutronix.de>



> ---
>  elbepack/shellhelper.py | 160 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 160 insertions(+)
> 
> diff --git a/elbepack/shellhelper.py b/elbepack/shellhelper.py
> index 203b5f4c..12b7673c 100644
> --- a/elbepack/shellhelper.py
> +++ b/elbepack/shellhelper.py
> @@ -28,6 +28,22 @@ class CommandError(Exception):
>              self.returncode, self.cmd)
>  
>  def system(cmd, allow_fail=False, env_add=None):
> +    """system() - Execute cmd in a shell.
> +
> +    Throws a CommandError if cmd returns none-zero and allow_fail=False
> +
> +    --
> +
> +    >>> system("true")
> +
> +    >>> system("false", allow_fail=True)
> +
> +    >>> system("$FALSE", env_add={"FALSE":"false"}) # doctest: +ELLIPSIS
> +    Traceback (most recent call last):
> +    ...
> +    elbepack.shellhelper.CommandError: ...
> +
> +    """
>      new_env = os.environ.copy()
>      if env_add:
>          new_env.update(env_add)
> @@ -40,6 +56,28 @@ def system(cmd, allow_fail=False, env_add=None):
>  
>  
>  def command_out(cmd, stdin=None, output=PIPE, env_add=None):
> +    """command_out() - Execute cmd in a shell.
> +
> +    Returns a tuple with the exitcode and the output of cmd.
> +
> +    --
> +
> +    >>> command_out("true")
> +    (0, '')
> +
> +    >>> command_out("$TRUE && true", env_add={"TRUE":"true"})
> +    (0, '')
> +
> +    >>> command_out("cat -", stdin=b"ELBE")
> +    (0, 'ELBE')
> +
> +    >>> command_out("2>&1 cat -", stdin=b"ELBE")
> +    (0, 'ELBE')
> +
> +    >>> command_out("false")
> +    (1, '')
> +
> +    """
>      new_env = os.environ.copy()
>      if env_add:
>          new_env.update(env_add)
> @@ -59,6 +97,22 @@ def command_out(cmd, stdin=None, output=PIPE, env_add=None):
>  
>  
>  def system_out(cmd, stdin=None, allow_fail=False, env_add=None):
> +    """system_out() - Wrapper around command_out().
> +
> +    On failure, raises an exception if allow_fail=False, on success,
> +    returns the output of cmd.
> +
> +    --
> +
> +    >>> system_out("false") # doctest: +ELLIPSIS
> +    Traceback (most recent call last):
> +    ...
> +    elbepack.shellhelper.CommandError: ...
> +
> +    >>> system_out("false", allow_fail=True)
> +    ''
> +
> +    """
>      code, out = command_out(cmd, stdin=stdin, env_add=env_add)
>  
>      if code != 0:
> @@ -69,6 +123,22 @@ def system_out(cmd, stdin=None, allow_fail=False, env_add=None):
>  
>  
>  def command_out_stderr(cmd, stdin=None, env_add=None):
> +    """command_out_stderr() - Execute cmd in a shell.
> +
> +    Returns a tuple of the exitcode, stdout and stderr of cmd.
> +
> +    --
> +
> +    >>> command_out_stderr("$TRUE && cat -", stdin=b"ELBE", env_add={"TRUE":"true"})
> +    (0, 'ELBE', '')
> +
> +    >>> command_out_stderr("1>&2 cat - && false", stdin=b"ELBE")
> +    (1, '', 'ELBE')
> +
> +    >>> command_out_stderr("true")
> +    (0, '', '')
> +
> +    """
>      new_env = os.environ.copy()
>      if env_add:
>          new_env.update(env_add)
> @@ -89,6 +159,24 @@ def command_out_stderr(cmd, stdin=None, env_add=None):
>  
>  
>  def system_out_stderr(cmd, stdin=None, allow_fail=False, env_add=None):
> +    """system_out_stderr() - Wrapper around command_out_stderr()
> +
> +    Throws CommandError if cmd failed and allow_fail=False.  Otherwise,
> +    returns the stdout and stderr of cmd.
> +
> +    --
> +
> +    >>> system_out_stderr("false") # doctest: +ELLIPSIS
> +    Traceback (most recent call last):
> +    ...
> +    elbepack.shellhelper.CommandError: ...
> +
> +    >>> system_out_stderr("cat - && false", allow_fail=True, stdin=b"ELBE")
> +    ('ELBE', '')
> +
> +    >>> system_out_stderr("1>&2 cat -", allow_fail=True, stdin=b"ELBE")
> +    ('', 'ELBE')
> +    """
>      code, out, err = command_out_stderr(cmd, stdin, env_add)
>  
>      if code != 0:
> @@ -99,6 +187,37 @@ def system_out_stderr(cmd, stdin=None, allow_fail=False, env_add=None):
>  
>  
>  def do(cmd, allow_fail=False, stdin=None, env_add=None):
> +    """do() - Execute cmd in a shell and redirect outputs to logging.
> +
> +    Throws a CommandError if cmd failed with allow_Fail=False.
> +
> +    --
> +
> +    Let's redirect the loggers to current stdout
> +    >>> import sys
> +    >>> from elbepack.log import open_logging
> +    >>> open_logging({"streams":sys.stdout})
> +
> +    >>> do("true")
> +    [CMD] true
> +
> +    >>> do("false", allow_fail=True)
> +    [CMD] false
> +
> +    >>> do("cat -", stdin=b"ELBE")
> +    [CMD] cat -
> +
> +    >>> do("cat - && false", stdin=b"ELBE") # doctest: +ELLIPSIS
> +    Traceback (most recent call last):
> +    ...
> +    elbepack.shellhelper.CommandError: ...
> +
> +    >>> do("false") # doctest: +ELLIPSIS
> +    Traceback (most recent call last):
> +    ...
> +    elbepack.shellhelper.CommandError: ...
> +    """
> +
>      new_env = os.environ.copy()
>      if env_add:
>          new_env.update(env_add)
> @@ -121,6 +240,22 @@ def do(cmd, allow_fail=False, stdin=None, env_add=None):
>  
>  
>  def chroot(directory, cmd, env_add=None, **kwargs):
> +    """chroot() - Wrapper around do().
> +
> +    --
> +
> +    Let's redirect the loggers to current stdout
> +
> +    >>> import sys
> +    >>> from elbepack.log import open_logging
> +    >>> open_logging({"streams":sys.stdout})
> +
> +    >>> chroot("/", "true") # doctest: +ELLIPSIS
> +    Traceback (most recent call last):
> +    ...
> +    elbepack.shellhelper.CommandError: ...
> +    """
> +
>      new_env = {"LANG":"C",
>                 "LANGUAGE":"C",
>                 "LC_ALL":"C"}
> @@ -130,6 +265,31 @@ def chroot(directory, cmd, env_add=None, **kwargs):
>      do(chcmd, env_add=new_env, **kwargs)
>  
>  def get_command_out(cmd, stdin=None, allow_fail=False, env_add={}):
> +    """get_command_out() - Like do() but returns stdout.
> +
> +    --
> +
> +    Let's quiet the loggers
> +
> +    >>> import os
> +    >>> from elbepack.log import open_logging
> +    >>> open_logging({"files":os.devnull})
> +
> +    >>> get_command_out("echo ELBE")
> +    b'ELBE\\n'
> +
> +    >>> get_command_out("false") # doctest: +ELLIPSIS
> +    Traceback (most recent call last):
> +    ...
> +    elbepack.shellhelper.CommandError: ...
> +
> +    >>> get_command_out("false", allow_fail=True)
> +    b''
> +
> +    >>> get_command_out("cat -", stdin=b"ELBE", env_add={"TRUE":"true"})
> +    b'ELBE'
> +    """
> +
>      new_env = os.environ.copy()
>      new_env.update(env_add)
>  
> -- 
> 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