mirror of
https://github.com/docker/compose.git
synced 2025-07-27 07:34:10 +02:00
Fix Project#build_container_operation_with_timeout_func not to mutate a 'option' dict over multiple containers
Signed-off-by: Yuichiro Tsuchiya <t.yic.yt@gmail.com>
This commit is contained in:
parent
768c788da9
commit
572032fc0b
@ -725,10 +725,11 @@ class Project(object):
|
|||||||
|
|
||||||
def build_container_operation_with_timeout_func(self, operation, options):
|
def build_container_operation_with_timeout_func(self, operation, options):
|
||||||
def container_operation_with_timeout(container):
|
def container_operation_with_timeout(container):
|
||||||
if options.get('timeout') is None:
|
_options = options.copy()
|
||||||
|
if _options.get('timeout') is None:
|
||||||
service = self.get_service(container.service)
|
service = self.get_service(container.service)
|
||||||
options['timeout'] = service.stop_timeout(None)
|
_options['timeout'] = service.stop_timeout(None)
|
||||||
return getattr(container, operation)(**options)
|
return getattr(container, operation)(**_options)
|
||||||
return container_operation_with_timeout
|
return container_operation_with_timeout
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@ from compose.config.types import VolumeFromSpec
|
|||||||
from compose.const import COMPOSEFILE_V1 as V1
|
from compose.const import COMPOSEFILE_V1 as V1
|
||||||
from compose.const import COMPOSEFILE_V2_0 as V2_0
|
from compose.const import COMPOSEFILE_V2_0 as V2_0
|
||||||
from compose.const import COMPOSEFILE_V2_4 as V2_4
|
from compose.const import COMPOSEFILE_V2_4 as V2_4
|
||||||
|
from compose.const import COMPOSEFILE_V3_7 as V3_7
|
||||||
|
from compose.const import DEFAULT_TIMEOUT
|
||||||
from compose.const import LABEL_SERVICE
|
from compose.const import LABEL_SERVICE
|
||||||
from compose.container import Container
|
from compose.container import Container
|
||||||
from compose.errors import OperationFailedError
|
from compose.errors import OperationFailedError
|
||||||
@ -765,6 +767,34 @@ class ProjectTest(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
assert project.get_service('web').platform == 'linux/s390x'
|
assert project.get_service('web').platform == 'linux/s390x'
|
||||||
|
|
||||||
|
def test_build_container_operation_with_timeout_func_does_not_mutate_options_with_timeout(self):
|
||||||
|
config_data = Config(
|
||||||
|
version=V3_7,
|
||||||
|
services=[
|
||||||
|
{'name': 'web', 'image': 'busybox:latest'},
|
||||||
|
{'name': 'db', 'image': 'busybox:latest', 'stop_grace_period': '1s'},
|
||||||
|
],
|
||||||
|
networks={}, volumes={}, secrets=None, configs=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
project = Project.from_config(name='test', client=self.mock_client, config_data=config_data)
|
||||||
|
|
||||||
|
stop_op = project.build_container_operation_with_timeout_func('stop', options={})
|
||||||
|
|
||||||
|
web_container = mock.create_autospec(Container, service='web')
|
||||||
|
db_container = mock.create_autospec(Container, service='db')
|
||||||
|
|
||||||
|
# `stop_grace_period` is not set to 'web' service,
|
||||||
|
# then it is stopped with the default timeout.
|
||||||
|
stop_op(web_container)
|
||||||
|
web_container.stop.assert_called_once_with(timeout=DEFAULT_TIMEOUT)
|
||||||
|
|
||||||
|
# `stop_grace_period` is set to 'db' service,
|
||||||
|
# then it is stopped with the specified timeout and
|
||||||
|
# the value is not overridden by the previous function call.
|
||||||
|
stop_op(db_container)
|
||||||
|
db_container.stop.assert_called_once_with(timeout=1)
|
||||||
|
|
||||||
@mock.patch('compose.parallel.ParallelStreamWriter._write_noansi')
|
@mock.patch('compose.parallel.ParallelStreamWriter._write_noansi')
|
||||||
def test_error_parallel_pull(self, mock_write):
|
def test_error_parallel_pull(self, mock_write):
|
||||||
project = Project.from_config(
|
project = Project.from_config(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user