From a058fdbcc38b9ecf3a9a6fce093a426eecd41212 Mon Sep 17 00:00:00 2001 From: Duncan Hall Date: Mon, 13 Feb 2017 17:02:26 +0000 Subject: [PATCH] Test all basic commands resolve to correct class --- README.rst | 23 +++++++++++ envmgr/cli.py | 21 ++++++---- envmgr/commands/service.py | 7 +--- setup.py | 25 +----------- tests/test_cli.py | 82 +++++++++++++++++++++++++++++++------- 5 files changed, 108 insertions(+), 50 deletions(-) diff --git a/README.rst b/README.rst index 57f2e69..195ac24 100644 --- a/README.rst +++ b/README.rst @@ -224,3 +224,26 @@ Or provide the hostname with each command: :: envmgr get MyService health in prod --host=environmentmanager.acme.com + + +Development +----------- +Install development dependencies: + +:: + + pip install -e . + + +Run Tests +^^^^^^^^^^ +Run all tests: + +:: + + pytest -v + + + + + diff --git a/envmgr/cli.py b/envmgr/cli.py index 9ec2bd7..a060e3e 100755 --- a/envmgr/cli.py +++ b/envmgr/cli.py @@ -50,6 +50,17 @@ from inspect import getmembers, isclass from docopt import docopt from . import __version__ as VERSION +from envmgr.commands import ASG, Deploy, Patch, Publish, Service, Toggle + +commands = { + 'asg':ASG, + 'deploy':Deploy, + 'patch':Patch, + 'publish':Publish, + 'service':Service, + 'toggle':Toggle +} + def except_hook(exec_type, value, trace_back): print(value) @@ -58,21 +69,17 @@ def except_hook(exec_type, value, trace_back): def main(): """Main CLI entrypoint.""" - import envmgr.commands - options = docopt(__doc__, version=VERSION) priority_order = ["asg", "deploy", "patch", "toggle", "publish", "service"] - cmd_opts = options.copy() + if cmd_opts[""] is not None: cmd_opts["service"] = True for cmd in priority_order: if cmd_opts[cmd]: - module = getattr(envmgr.commands, cmd) - envmgr.commands = getmembers(module, isclass) - command = [command[1] for command in envmgr.commands if command[0] != 'BaseCommand'][0] - command = command(options) + CommandClass = commands[cmd] + command = CommandClass(options) command.run() return diff --git a/envmgr/commands/service.py b/envmgr/commands/service.py index 00d3de4..e5de45b 100755 --- a/envmgr/commands/service.py +++ b/envmgr/commands/service.py @@ -6,7 +6,7 @@ from json import dumps from envmgr.commands.base import BaseCommand -class GetService(BaseCommand): +class Service(BaseCommand): def run(self): if self.cmds['healthy']: @@ -18,7 +18,6 @@ def run(self): self.get_overall_health(**self.cli_args) elif self.cmds['slice']: self.get_service_slice(**self.cli_args) - def wait_for_healthy_service(self, service, env, slice=None): while True: @@ -35,21 +34,18 @@ def get_overall_health(self, service, env): self.show_result(result, messages) return all( service["OverallHealth"] == "Healthy" for service in services ) - def get_service_health(self, service, slice, env): result = self.api.get_service_health(service, env, slice) message = self.format_health(result) self.show_result(result, message) return result["OverallHealth"] == "Healthy" - def get_service_slice(self, service, env): active = "true" if self.cmds['active'] else "false" result = self.api.get_service_slices(service, env, active) messages = [ self.format_slice(slice) for slice in result ] self.show_result(result, messages) - def format_health(self, service): slice = service['Slice'] status = service['OverallHealth'] @@ -57,7 +53,6 @@ def format_health(self, service): n_total = service['InstancesCount']['Total'] return "{0} is {1} ({2} of {3} instances Healthy)".format(slice, status, n_healthy, n_total) - def format_slice(self, slice): name = slice['Name'] status = slice['State'] diff --git a/setup.py b/setup.py index e6d0cd5..0567164 100755 --- a/setup.py +++ b/setup.py @@ -1,34 +1,14 @@ """ Copyright (c) Trainline Limited, 2017. All rights reserved. See LICENSE.txt in the project root for license information. """ -from setuptools import Command, find_packages, setup +from setuptools import find_packages, setup from codecs import open from os.path import abspath, dirname, join -from subprocess import call - from envmgr import __version__ this_dir = abspath(dirname(__file__)) with open(join(this_dir, 'README.rst'), encoding='utf-8') as file: long_description = file.read() - -class RunTests(Command): - - description = 'run tests' - user_options = [] - - def initialize_options(self): - pass - - def finalize_options(self): - pass - - def run(self): - print('is it running') - errno = call(['py.test', '--cov=envmgr', '--cov-report=term-missing']) - #raise SystemExit(errno) - - setup( name = 'envmgr-cli', version = __version__, @@ -46,13 +26,12 @@ def run(self): 'environment_manager==0.0.9' ], extras_require = { - 'test': ['coverage', 'pytest', 'pytest-cov'] + 'test': ['pytest', 'mock'] }, entry_points = { 'console_scripts': [ 'envmgr=envmgr.cli:main', ], }, - cmdclass = {'test':RunTests}, ) diff --git a/tests/test_cli.py b/tests/test_cli.py index a885476..577977c 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,22 +1,76 @@ - """ CLI entry point tests """ -from subprocess import PIPE, Popen as popen +import sys + from unittest import TestCase -from envmgr import __version__ as VERSION +from mock import patch +from envmgr.cli import main -from envmgr import cli +class TestCLI(TestCase): -# @patch('environment_manager.EMApi') + @patch('envmgr.cli.Service.run') + def test_get_service_health(self, run): + self.assert_command('get MockService health in mk-1', run) -class TestCLI(TestCase): + @patch('envmgr.cli.Service.run') + def test_get_service_health_with_slice(self, run): + self.assert_command('get AcmeService health in mk-2 green', run) + + @patch('envmgr.cli.Service.run') + def test_get_service_active_slice(self, run): + self.assert_command('get CoolService active slice in mk-22', run) + + @patch('envmgr.cli.Service.run') + def test_get_service_inactive_slice(self, run): + self.assert_command('get CoolService inactive slice in mk-22', run) + + @patch('envmgr.cli.Service.run') + def test_wait_for_healthy_service(self, run): + self.assert_command('wait-for healthy CoolService in mk-22', run) + + @patch('envmgr.cli.ASG.run') + def test_get_asg_status(self, run): + self.assert_command('get asg mk-auto-scale status in mk-22', run) + + @patch('envmgr.cli.ASG.run') + def test_get_asg_schedule(self, run): + self.assert_command('get asg mk-auto-scale schedule in mk-22', run) + + @patch('envmgr.cli.ASG.run') + def test_wait_for_asg(self, run): + self.assert_command('wait-for asg mk-auto-scale in mk-22', run) + + @patch('envmgr.cli.ASG.run') + def test_schedule_asg(self, run): + self.assert_command('schedule asg mk-auto-scale on in mk-22', run) + + @patch('envmgr.cli.Deploy.run') + def test_deploy_service(self, run): + self.assert_command('deploy MyService 1.4.0 in prod-1', run) + + @patch('envmgr.cli.Deploy.run') + def test_get_deploy_status(self, run): + self.assert_command('get deploy status a2fbb0c0-ed4c-11e6-85b1-2b6d1cb68994', run) + + @patch('envmgr.cli.Deploy.run') + def test_wait_for_deploy(self, run): + self.assert_command('wait-for deploy a2fbb0c0-ed4c-11e6-85b1-2b6d1cb68994', run) + + @patch('envmgr.cli.Publish.run') + def test_publish_service(self, run): + self.assert_command('publish build-22.zip as AcmeService 1.2.3', run) + + @patch('envmgr.cli.Toggle.run') + def test_toggle_service(self, run): + self.assert_command('toggle MyService in mock-3', run) + + @patch('envmgr.cli.Patch.run') + def test_get_patch_status(self, run): + self.assert_command('get team-1 patch status in prod', run) - """ - def test_returns_version_info(self): - output = popen(['envmgr', '--version'], stdout=PIPE).communicate()[0] - self.assertEqual(output.strip(), VERSION) - """ + def assert_command(self, cmd, func): + argv = ['/usr/local/bin/envmgr'] + cmd.split(' ') + with patch.object(sys, 'argv', argv): + main() + func.assert_called_once() - def test_service_health(self): - cli.main() - self.assertEqual(1,2)