Charmed-Kubernetes/nrpe/mod/charmhelpers/tests/cli/test_cmdline.py

237 lines
7.7 KiB
Python

"""Tests for the commandant code that analyzes a function signature to
determine the parameters to argparse."""
from unittest import TestCase
from mock import (
patch,
MagicMock,
ANY,
)
import json
from pprint import pformat
import yaml
import csv
from six import StringIO
from charmhelpers import cli
class SubCommandTest(TestCase):
"""Test creation of subcommands"""
def setUp(self):
super(SubCommandTest, self).setUp()
self.cl = cli.CommandLine()
@patch('sys.exit')
def test_subcommand_wrapper(self, _sys_exit):
"""Test function name detection"""
@self.cl.subcommand()
def payload():
"A function that does work."
pass
args = self.cl.argument_parser.parse_args(['payload'])
self.assertEqual(args.func, payload)
self.assertEqual(_sys_exit.mock_calls, [])
@patch('sys.exit')
def test_subcommand_wrapper_bogus_arguments(self, _sys_exit):
"""Test function name detection"""
@self.cl.subcommand()
def payload():
"A function that does work."
pass
with self.assertRaises(TypeError):
with patch("sys.argv", "tests deliberately bad input".split()):
with patch("sys.stderr"):
self.cl.argument_parser.parse_args()
_sys_exit.assert_called_once_with(2)
@patch('sys.exit')
def test_subcommand_wrapper_cmdline_options(self, _sys_exit):
"""Test detection of positional arguments and optional parameters."""
@self.cl.subcommand()
def payload(x, y=None):
"A function that does work."
return x
args = self.cl.argument_parser.parse_args(['payload', 'positional', '--y=optional'])
self.assertEqual(args.func, payload)
self.assertEqual(args.x, 'positional')
self.assertEqual(args.y, 'optional')
self.assertEqual(_sys_exit.mock_calls, [])
@patch('sys.exit')
def test_subcommand_builder(self, _sys_exit):
def noop(z):
pass
@self.cl.subcommand_builder('payload', description="A subcommand")
def payload_command(subparser):
subparser.add_argument('-z', action='store_true')
return noop
args = self.cl.argument_parser.parse_args(['payload', '-z'])
self.assertEqual(args.func, noop)
self.assertTrue(args.z)
self.assertFalse(_sys_exit.called)
def test_subcommand_builder_bogus_wrapped_args(self):
with self.assertRaises(TypeError):
@self.cl.subcommand_builder('payload', description="A subcommand")
def payload_command(subparser, otherarg):
pass
def test_run(self):
self.bar_called = False
@self.cl.subcommand()
def bar(x, y=None, *vargs):
"A function that does work."
self.assertEqual(x, 'baz')
self.assertEqual(y, 'why')
self.assertEqual(vargs, ('mux', 'zob'))
self.bar_called = True
return "qux"
args = ['chlp', 'bar', '--y', 'why', 'baz', 'mux', 'zob']
self.cl.formatter = MagicMock()
with patch("sys.argv", args):
with patch("charmhelpers.core.unitdata._KV") as _KV:
self.cl.run()
assert _KV.flush.called
self.assertTrue(self.bar_called)
self.cl.formatter.format_output.assert_called_once_with('qux', ANY)
def test_no_output(self):
self.bar_called = False
@self.cl.subcommand()
@self.cl.no_output
def bar(x, y=None, *vargs):
"A function that does work."
self.bar_called = True
return "qux"
args = ['foo', 'bar', 'baz']
self.cl.formatter = MagicMock()
with patch("sys.argv", args):
self.cl.run()
self.assertTrue(self.bar_called)
self.cl.formatter.format_output.assert_called_once_with('', ANY)
def test_test_command(self):
self.bar_called = False
self.bar_result = True
@self.cl.subcommand()
@self.cl.test_command
def bar(x, y=None, *vargs):
"A function that does work."
self.bar_called = True
return self.bar_result
args = ['foo', 'bar', 'baz']
self.cl.formatter = MagicMock()
with patch("sys.argv", args):
self.cl.run()
self.assertTrue(self.bar_called)
self.assertEqual(self.cl.exit_code, 0)
self.cl.formatter.format_output.assert_called_once_with('', ANY)
self.bar_result = False
with patch("sys.argv", args):
self.cl.run()
self.assertEqual(self.cl.exit_code, 1)
class OutputFormatterTest(TestCase):
def setUp(self):
super(OutputFormatterTest, self).setUp()
self.expected_formats = (
"raw",
"json",
"py",
"yaml",
"csv",
"tab",
)
self.outfile = StringIO()
self.of = cli.OutputFormatter(outfile=self.outfile)
self.output_data = {"this": "is", "some": 1, "data": dict()}
def test_supports_formats(self):
self.assertEqual(sorted(self.expected_formats),
sorted(self.of.supported_formats))
def test_adds_arguments(self):
ap = MagicMock()
arg_group = MagicMock()
add_arg = MagicMock()
arg_group.add_argument = add_arg
ap.add_mutually_exclusive_group.return_value = arg_group
self.of.add_arguments(ap)
self.assertTrue(add_arg.called)
for call_args in add_arg.call_args_list:
if "--format" in call_args[0]:
self.assertEqual(sorted(call_args[1]['choices']),
sorted(self.expected_formats))
self.assertEqual(call_args[1]['default'], 'raw')
break
else:
print(arg_group.call_args_list)
self.fail("No --format argument was created")
all_args = [c[0][0] for c in add_arg.call_args_list]
all_args.extend([c[0][1] for c in add_arg.call_args_list if len(c[0]) > 1])
for fmt in self.expected_formats:
self.assertIn("-{}".format(fmt[0]), all_args)
self.assertIn("--{}".format(fmt), all_args)
def test_outputs_raw(self):
self.of.raw(self.output_data)
self.outfile.seek(0)
self.assertEqual(self.outfile.read(), str(self.output_data))
def test_outputs_json(self):
self.of.json(self.output_data)
self.outfile.seek(0)
self.assertEqual(self.outfile.read(), json.dumps(self.output_data))
def test_outputs_py(self):
self.of.py(self.output_data)
self.outfile.seek(0)
self.assertEqual(self.outfile.read(), pformat(self.output_data) + "\n")
def test_outputs_yaml(self):
self.of.yaml(self.output_data)
self.outfile.seek(0)
self.assertEqual(self.outfile.read(), yaml.dump(self.output_data))
def test_outputs_csv(self):
sample = StringIO()
writer = csv.writer(sample)
writer.writerows(self.output_data)
sample.seek(0)
self.of.csv(self.output_data)
self.outfile.seek(0)
self.assertEqual(self.outfile.read(), sample.read())
def test_outputs_tab(self):
sample = StringIO()
writer = csv.writer(sample, dialect=csv.excel_tab)
writer.writerows(self.output_data)
sample.seek(0)
self.of.tab(self.output_data)
self.outfile.seek(0)
self.assertEqual(self.outfile.read(), sample.read())
def test_formats_output(self):
for format in self.expected_formats:
mock_f = MagicMock()
setattr(self.of, format, mock_f)
self.of.format_output(self.output_data, format)
mock_f.assert_called_with(self.output_data)