Skip to content

Commit

Permalink
add support for unit testing butler commands
Browse files Browse the repository at this point in the history
  • Loading branch information
n8pease committed May 12, 2020
1 parent 5ae976a commit 1f977fa
Showing 1 changed file with 63 additions and 0 deletions.
63 changes: 63 additions & 0 deletions python/lsst/daf/butler/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,19 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import click
import os

from ..core.utils import iterable


# DAF_BUTLER_MOCK is set by some tests as an environment variable and indicates
# to the cli_handle_exception function that instead of executing the command
# implementation function it should print details about the called command to
# stdout. These details are then used to verify the command function was loaded
# and received expected inputs.
DAF_BUTLER_MOCK = {"DAF_BUTLER_MOCK": ""}


def split_commas(context, param, values):
"""Process a tuple of values, where each value may contain comma-separated
values, and return a single list of all the passed-in values.
Expand Down Expand Up @@ -123,10 +132,59 @@ def to_upper(context, param, value):
return value.upper()


def printFunctionInfo(func, *args, **kwargs):
"""For unit testing butler subcommand call execution, write a dict to
stdout that formats information about a funciton call into a dict that can
be evaluated by `verifyFunctionInfo`
Parameters
----------
func : function
The function that has been called, whose name should be written.
args : [`str`]
The values of the arguments the function was called with.
kwags : `dict` [`str`, `str`]
The names and values of the kwargs the function was called with.
"""
print(dict(function=func.__name__,
args=args,
kwargs=kwargs))


def verifyFunctionInfo(testSuite, output, function, expectedArgs, expectedKwargs):
"""For unit testing butler subcommand call execution, compare a dict that
has been printed to stdout to expected data.
Parameters
----------
testSuite : `unittest.Testsuite`
The test suite that is executing a unit test.
output : `str`
The dict that has been printed to stdout. It should be formatted to
re-instantiate by calling `eval`.
function : `str`
The name of the function that was was expected to have been called.
expectedArgs : [`str`]
The values of the arguments that should have been passed to the
function.
expectedKwargs : `dict` [`str`, `str`]
The names and values of the kwargs that should have been passsed to the
funciton.
"""
calledWith = eval(output)
testSuite.assertEqual(calledWith['function'], function)
testSuite.assertEqual(calledWith['args'], expectedArgs)
testSuite.assertEqual(calledWith['kwargs'], expectedKwargs)


def cli_handle_exception(func, *args, **kwargs):
"""Wrap a function call in an exception handler that raises a
ClickException if there is an Exception.
Also provides support for unit testing by testing for an environment
variable, and if it is present prints the function name, args, and kwargs
to stdout so they can be read and verified by the unit test code.
Parameters
----------
func : function
Expand All @@ -142,6 +200,11 @@ def cli_handle_exception(func, *args, **kwargs):
click.ClickException
An exception to be handled by the Click CLI tool.
"""
# "DAF_BUTLER_MOCK" matches the key in the variable DAF_BUTLER_MOCK,
# defined in the top of this file.
if "DAF_BUTLER_MOCK" in os.environ:
printFunctionInfo(func, *args, **kwargs)
return
try:
return func(*args, **kwargs)
except Exception as err:
Expand Down

0 comments on commit 1f977fa

Please sign in to comment.