mirror of https://github.com/docker/compose.git
Merge pull request #2832 from aanand/refactor-cli-unit-tests
Refactor CLI initialization and unit tests
This commit is contained in:
commit
4ae71f41dd
|
@ -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
|
||||
|
|
|
@ -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']
|
||||
|
||||
|
|
|
@ -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)])
|
|
@ -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"],
|
||||
|
|
|
@ -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': [],
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue