Merge pull request #2832 from aanand/refactor-cli-unit-tests

Refactor CLI initialization and unit tests
This commit is contained in:
Aanand Prasad 2016-03-02 16:10:44 -08:00
commit 4ae71f41dd
6 changed files with 72 additions and 101 deletions

View File

@ -10,7 +10,7 @@
- id: end-of-file-fixer
- id: flake8
- id: name-tests-test
exclude: 'tests/integration/testcases.py'
exclude: 'tests/(helpers\.py|integration/testcases\.py)'
- id: requirements-txt-fixer
- id: trailing-whitespace
- repo: git://github.com/asottile/reorder_python_imports

View File

@ -20,12 +20,12 @@ class DocoptCommand(object):
return {'options_first': True}
def sys_dispatch(self):
self.dispatch(sys.argv[1:], None)
self.dispatch(sys.argv[1:])
def dispatch(self, argv, global_options):
self.perform_command(*self.parse(argv, global_options))
def dispatch(self, argv):
self.perform_command(*self.parse(argv))
def parse(self, argv, global_options):
def parse(self, argv):
options = docopt_full_help(getdoc(self), argv, **self.docopt_options())
command = options['COMMAND']

16
tests/helpers.py Normal file
View File

@ -0,0 +1,16 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from compose.config.config import ConfigDetails
from compose.config.config import ConfigFile
from compose.config.config import load
def build_config(contents, **kwargs):
return load(build_config_details(contents, **kwargs))
def build_config_details(contents, working_dir='working_dir', filename='filename.yml'):
return ConfigDetails(
working_dir,
[ConfigFile(filename, contents)])

View File

@ -7,6 +7,7 @@ import py
import pytest
from docker.errors import NotFound
from ..helpers import build_config
from .testcases import DockerClientTestCase
from compose.config import config
from compose.config import ConfigurationError
@ -20,13 +21,6 @@ from compose.service import ConvergenceStrategy
from tests.integration.testcases import v2_only
def build_service_dicts(service_config):
return config.load(
config.ConfigDetails(
'working_dir',
[config.ConfigFile(None, service_config)]))
class ProjectTest(DockerClientTestCase):
def test_containers(self):
@ -67,19 +61,18 @@ class ProjectTest(DockerClientTestCase):
)
def test_volumes_from_service(self):
service_dicts = build_service_dicts({
'data': {
'image': 'busybox:latest',
'volumes': ['/var/data'],
},
'db': {
'image': 'busybox:latest',
'volumes_from': ['data'],
},
})
project = Project.from_config(
name='composetest',
config_data=service_dicts,
config_data=build_config({
'data': {
'image': 'busybox:latest',
'volumes': ['/var/data'],
},
'db': {
'image': 'busybox:latest',
'volumes_from': ['data'],
},
}),
client=self.client,
)
db = project.get_service('db')
@ -96,7 +89,7 @@ class ProjectTest(DockerClientTestCase):
)
project = Project.from_config(
name='composetest',
config_data=build_service_dicts({
config_data=build_config({
'db': {
'image': 'busybox:latest',
'volumes_from': ['composetest_data_container'],
@ -112,7 +105,7 @@ class ProjectTest(DockerClientTestCase):
project = Project.from_config(
name='composetest',
client=self.client,
config_data=build_service_dicts({
config_data=build_config({
'version': V2_0,
'services': {
'net': {
@ -139,7 +132,7 @@ class ProjectTest(DockerClientTestCase):
def get_project():
return Project.from_config(
name='composetest',
config_data=build_service_dicts({
config_data=build_config({
'version': V2_0,
'services': {
'web': {
@ -174,7 +167,7 @@ class ProjectTest(DockerClientTestCase):
def test_net_from_service_v1(self):
project = Project.from_config(
name='composetest',
config_data=build_service_dicts({
config_data=build_config({
'net': {
'image': 'busybox:latest',
'command': ["top"]
@ -198,7 +191,7 @@ class ProjectTest(DockerClientTestCase):
def get_project():
return Project.from_config(
name='composetest',
config_data=build_service_dicts({
config_data=build_config({
'web': {
'image': 'busybox:latest',
'net': 'container:composetest_net_container'
@ -469,7 +462,7 @@ class ProjectTest(DockerClientTestCase):
def test_project_up_starts_depends(self):
project = Project.from_config(
name='composetest',
config_data=build_service_dicts({
config_data=build_config({
'console': {
'image': 'busybox:latest',
'command': ["top"],
@ -504,7 +497,7 @@ class ProjectTest(DockerClientTestCase):
def test_project_up_with_no_deps(self):
project = Project.from_config(
name='composetest',
config_data=build_service_dicts({
config_data=build_config({
'console': {
'image': 'busybox:latest',
'command': ["top"],

View File

@ -10,13 +10,14 @@ import pytest
from .. import mock
from .. import unittest
from ..helpers import build_config
from compose.cli.command import get_project
from compose.cli.command import get_project_name
from compose.cli.docopt_command import NoSuchCommand
from compose.cli.errors import UserError
from compose.cli.main import TopLevelCommand
from compose.const import IS_WINDOWS_PLATFORM
from compose.service import Service
from compose.project import Project
class CLITestCase(unittest.TestCase):
@ -66,17 +67,17 @@ class CLITestCase(unittest.TestCase):
def test_help(self):
command = TopLevelCommand()
with self.assertRaises(SystemExit):
command.dispatch(['-h'], None)
command.dispatch(['-h'])
def test_command_help(self):
with self.assertRaises(SystemExit) as ctx:
TopLevelCommand().dispatch(['help', 'up'], None)
TopLevelCommand().dispatch(['help', 'up'])
self.assertIn('Usage: up', str(ctx.exception))
def test_command_help_nonexistent(self):
with self.assertRaises(NoSuchCommand):
TopLevelCommand().dispatch(['help', 'nonexistent'], None)
TopLevelCommand().dispatch(['help', 'nonexistent'])
@pytest.mark.xfail(IS_WINDOWS_PLATFORM, reason="requires dockerpty")
@mock.patch('compose.cli.main.RunOperation', autospec=True)
@ -84,18 +85,19 @@ class CLITestCase(unittest.TestCase):
def test_run_interactive_passes_logs_false(self, mock_pseudo_terminal, mock_run_operation):
command = TopLevelCommand()
mock_client = mock.create_autospec(docker.Client)
mock_project = mock.Mock(client=mock_client)
mock_project.get_service.return_value = Service(
'service',
project = Project.from_config(
name='composetest',
client=mock_client,
environment=['FOO=ONE', 'BAR=TWO'],
image='someimage')
config_data=build_config({
'service': {'image': 'busybox'}
}),
)
with pytest.raises(SystemExit):
command.run(mock_project, {
command.run(project, {
'SERVICE': 'service',
'COMMAND': None,
'-e': ['BAR=NEW', 'OTHER=bär'.encode('utf-8')],
'-e': [],
'--user': None,
'--no-deps': None,
'-d': False,
@ -110,49 +112,22 @@ class CLITestCase(unittest.TestCase):
_, _, call_kwargs = mock_run_operation.mock_calls[0]
assert call_kwargs['logs'] is False
@pytest.mark.xfail(IS_WINDOWS_PLATFORM, reason="requires dockerpty")
@mock.patch('compose.cli.main.PseudoTerminal', autospec=True)
def test_run_with_environment_merged_with_options_list(self, mock_pseudo_terminal):
command = TopLevelCommand()
def test_run_service_with_restart_always(self):
mock_client = mock.create_autospec(docker.Client)
mock_project = mock.Mock(client=mock_client)
mock_project.get_service.return_value = Service(
'service',
project = Project.from_config(
name='composetest',
client=mock_client,
environment=['FOO=ONE', 'BAR=TWO'],
image='someimage')
command.run(mock_project, {
'SERVICE': 'service',
'COMMAND': None,
'-e': ['BAR=NEW', 'OTHER=bär'.encode('utf-8')],
'--user': None,
'--no-deps': None,
'-d': True,
'-T': None,
'--entrypoint': None,
'--service-ports': None,
'--publish': [],
'--rm': None,
'--name': None,
})
_, _, call_kwargs = mock_client.create_container.mock_calls[0]
assert (
sorted(call_kwargs['environment']) ==
sorted(['FOO=ONE', 'BAR=NEW', 'OTHER=bär'])
config_data=build_config({
'service': {
'image': 'busybox',
'restart': 'always',
}
}),
)
def test_run_service_with_restart_always(self):
command = TopLevelCommand()
mock_client = mock.create_autospec(docker.Client)
mock_project = mock.Mock(client=mock_client)
mock_project.get_service.return_value = Service(
'service',
client=mock_client,
restart={'Name': 'always', 'MaximumRetryCount': 0},
image='someimage')
command.run(mock_project, {
command.run(project, {
'SERVICE': 'service',
'COMMAND': None,
'-e': [],
@ -173,14 +148,7 @@ class CLITestCase(unittest.TestCase):
)
command = TopLevelCommand()
mock_client = mock.create_autospec(docker.Client)
mock_project = mock.Mock(client=mock_client)
mock_project.get_service.return_value = Service(
'service',
client=mock_client,
restart='always',
image='someimage')
command.run(mock_project, {
command.run(project, {
'SERVICE': 'service',
'COMMAND': None,
'-e': [],
@ -201,17 +169,16 @@ class CLITestCase(unittest.TestCase):
def test_command_manula_and_service_ports_together(self):
command = TopLevelCommand()
mock_client = mock.create_autospec(docker.Client)
mock_project = mock.Mock(client=mock_client)
mock_project.get_service.return_value = Service(
'service',
client=mock_client,
restart='always',
image='someimage',
project = Project.from_config(
name='composetest',
client=None,
config_data=build_config({
'service': {'image': 'busybox'},
}),
)
with self.assertRaises(UserError):
command.run(mock_project, {
command.run(project, {
'SERVICE': 'service',
'COMMAND': None,
'-e': [],

View File

@ -11,6 +11,7 @@ from operator import itemgetter
import py
import pytest
from ...helpers import build_config_details
from compose.config import config
from compose.config.config import resolve_build_args
from compose.config.config import resolve_environment
@ -43,12 +44,6 @@ def service_sort(services):
return sorted(services, key=itemgetter('name'))
def build_config_details(contents, working_dir='working_dir', filename='filename.yml'):
return config.ConfigDetails(
working_dir,
[config.ConfigFile(filename, contents)])
class ConfigTest(unittest.TestCase):
def test_load(self):
service_dicts = config.load(