| # Copyright 2012 The ChromiumOS Authors | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| """Tests for the command module.""" | |
| import argparse | |
| import importlib | |
| import os | |
| from chromite.cli import command | |
| from chromite.lib import commandline | |
| from chromite.lib import cros_test_lib | |
| from chromite.lib import partial_mock | |
| # pylint:disable=protected-access | |
| _COMMAND_NAME = "superAwesomeCommandOfFunness" | |
| @command.command_decorator(_COMMAND_NAME) | |
| class TestCommand(command.CliCommand): | |
| """A fake command.""" | |
| def Run(self): | |
| print("Just testing") | |
| class TestCommandTest(cros_test_lib.MockTestCase): | |
| """This test class tests that Commands method.""" | |
| def testParserSetsCommandClass(self): | |
| """Tests that our parser sets command_class correctly.""" | |
| my_parser = argparse.ArgumentParser() | |
| command.CliCommand.AddParser(my_parser) | |
| ns = my_parser.parse_args([]) | |
| self.assertEqual(ns.command_class, command.CliCommand) | |
| def testCommandDecorator(self): | |
| """Tests that our decorator correctly adds TestCommand to _commands.""" | |
| # Note this exposes an implementation detail of _commands. | |
| self.assertEqual(command._commands[_COMMAND_NAME], TestCommand) | |
| def testBadUseOfCommandDecorator(self): | |
| """Tests that our decorator correctly rejects bad test commands.""" | |
| try: | |
| # pylint: disable=unused-variable | |
| @command.command_decorator("bad") | |
| class BadTestCommand: | |
| """A command that wasn't implemented correctly.""" | |
| except command.InvalidCommandError: | |
| pass | |
| else: | |
| self.fail("Invalid command was accepted by @command_decorator") | |
| def testAddDeviceArgument(self): | |
| """Tests CliCommand.AddDeviceArgument().""" | |
| parser = argparse.ArgumentParser() | |
| command.CliCommand.AddDeviceArgument(parser, positional=True) | |
| # Device should be a positional argument. | |
| parser.parse_args(["device"]) | |
| def testAddNamedDeviceArgument(self): | |
| """Tests CliCommand.AddDeviceArgument().""" | |
| parser = argparse.ArgumentParser() | |
| command.CliCommand.AddDeviceArgument(parser, positional=False) | |
| # Device should be a named argument. | |
| parser.parse_args(["--device=device"]) | |
| parser.parse_args(["-d", "device"]) | |
| class MockCommand(partial_mock.PartialMock): | |
| """Mock class for a generic CLI command.""" | |
| ATTRS = ("Run",) | |
| COMMAND = None | |
| TARGET_CLASS = None | |
| def __init__(self, args, base_args=None): | |
| partial_mock.PartialMock.__init__(self) | |
| self.args = args | |
| self.rc_mock = cros_test_lib.RunCommandMock() | |
| self.rc_mock.SetDefaultCmdResult() | |
| self.parser = parser = commandline.ArgumentParser(caching=True) | |
| subparsers = parser.add_subparsers() | |
| subparser = subparsers.add_parser( | |
| self.COMMAND, | |
| caching=self.TARGET_CLASS.use_caching_options, | |
| dryrun=self.TARGET_CLASS.use_dryrun_options, | |
| ) | |
| self.TARGET_CLASS.AddParser(subparser) | |
| args = base_args if base_args else [] | |
| args += [self.COMMAND] + self.args | |
| options = parser.parse_args(args) | |
| self.inst = options.command_class(options) | |
| def Run(self, inst): | |
| with self.rc_mock: | |
| return self.backup["Run"](inst) | |
| class CommandTest(cros_test_lib.MockTestCase): | |
| """This test class tests that we can load modules correctly.""" | |
| def testFindModules(self): | |
| """Tests that we can return modules correctly when mocking out glob.""" | |
| fake_command_file = "cros_command_test.py" | |
| filtered_file = "cros_command_unittest.py" | |
| self.PatchObject( | |
| os, "listdir", return_value=[fake_command_file, filtered_file] | |
| ) | |
| self.assertEqual(command.ListCommands(), {"command-test"}) | |
| def testLoadCommands(self): | |
| """Tests import commands correctly.""" | |
| fake_module = "cros_command_test" | |
| module_path = "chromite.cli.cros.%s" % fake_module | |
| # The code doesn't use the return value, so stub it out lazy-like. | |
| load_mock = self.PatchObject( | |
| importlib, "import_module", return_value=None | |
| ) | |
| command._commands["command-test"] = 123 | |
| self.assertEqual(command.ImportCommand("command-test"), 123) | |
| command._commands.pop("command-test") | |
| load_mock.assert_called_with(module_path) | |
| def testListCrosCommands(self): | |
| """Tests we get a correct `cros` list back.""" | |
| cros_commands = command.ListCommands() | |
| # Pick some commands that are likely to not go away. | |
| self.assertIn("chrome-sdk", cros_commands) | |
| self.assertIn("flash", cros_commands) |