| # -*- coding: utf-8 -*- |
| # Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| # 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.""" |
| |
| from __future__ import print_function |
| |
| 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.CommandDecorator(_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.CommandDecorator('bad') |
| class BadTestCommand(object): |
| """A command that wasn't implemented correctly.""" |
| |
| except command.InvalidCommandError: |
| pass |
| else: |
| self.fail('Invalid command was accepted by the CommandDecorator') |
| |
| 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() |
| parser = commandline.ArgumentParser(caching=True) |
| subparsers = parser.add_subparsers() |
| subparser = subparsers.add_parser(self.COMMAND, caching=True) |
| 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 sane `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) |