mirror of
https://github.com/docker/compose.git
synced 2025-07-21 20:54:32 +02:00
Do less work during integration testing.
Signed-off-by: Daniel Nephin <dnephin@gmail.com>
This commit is contained in:
parent
6b221d5687
commit
e0b0801e87
@ -1,11 +1,13 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from docker.errors import APIError
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from docker.errors import APIError
|
||||||
|
|
||||||
from .container import Container
|
from .container import Container
|
||||||
from .progress_stream import stream_output, StreamOutputError
|
from .progress_stream import stream_output, StreamOutputError
|
||||||
|
|
||||||
@ -43,6 +45,9 @@ class ConfigError(ValueError):
|
|||||||
VolumeSpec = namedtuple('VolumeSpec', 'external internal mode')
|
VolumeSpec = namedtuple('VolumeSpec', 'external internal mode')
|
||||||
|
|
||||||
|
|
||||||
|
ServiceName = namedtuple('ServiceName', 'project service number')
|
||||||
|
|
||||||
|
|
||||||
class Service(object):
|
class Service(object):
|
||||||
def __init__(self, name, client=None, project='default', links=None, volumes_from=None, **options):
|
def __init__(self, name, client=None, project='default', links=None, volumes_from=None, **options):
|
||||||
if not re.match('^%s+$' % VALID_NAME_CHARS, name):
|
if not re.match('^%s+$' % VALID_NAME_CHARS, name):
|
||||||
@ -185,8 +190,8 @@ class Service(object):
|
|||||||
"""
|
"""
|
||||||
containers = self.containers(stopped=True)
|
containers = self.containers(stopped=True)
|
||||||
|
|
||||||
if len(containers) == 0:
|
if not containers:
|
||||||
log.info("Creating %s..." % self.next_container_name())
|
log.info("Creating %s..." % self._next_container_name(containers))
|
||||||
container = self.create_container(**override_options)
|
container = self.create_container(**override_options)
|
||||||
self.start_container(container)
|
self.start_container(container)
|
||||||
return [(None, container)]
|
return [(None, container)]
|
||||||
@ -264,7 +269,7 @@ class Service(object):
|
|||||||
containers = self.containers(stopped=True)
|
containers = self.containers(stopped=True)
|
||||||
|
|
||||||
if not containers:
|
if not containers:
|
||||||
log.info("Creating %s..." % self.next_container_name())
|
log.info("Creating %s..." % self._next_container_name(containers))
|
||||||
new_container = self.create_container()
|
new_container = self.create_container()
|
||||||
return [self.start_container(new_container)]
|
return [self.start_container(new_container)]
|
||||||
else:
|
else:
|
||||||
@ -273,19 +278,15 @@ class Service(object):
|
|||||||
def get_linked_names(self):
|
def get_linked_names(self):
|
||||||
return [s.name for (s, _) in self.links]
|
return [s.name for (s, _) in self.links]
|
||||||
|
|
||||||
def next_container_name(self, one_off=False):
|
def _next_container_name(self, all_containers, one_off=False):
|
||||||
bits = [self.project, self.name]
|
bits = [self.project, self.name]
|
||||||
if one_off:
|
if one_off:
|
||||||
bits.append('run')
|
bits.append('run')
|
||||||
return '_'.join(bits + [str(self.next_container_number(one_off=one_off))])
|
return '_'.join(bits + [str(self._next_container_number(all_containers))])
|
||||||
|
|
||||||
def next_container_number(self, one_off=False):
|
def _next_container_number(self, all_containers):
|
||||||
numbers = [parse_name(c.name)[2] for c in self.containers(stopped=True, one_off=one_off)]
|
numbers = [parse_name(c.name).number for c in all_containers]
|
||||||
|
return 1 if not numbers else max(numbers) + 1
|
||||||
if len(numbers) == 0:
|
|
||||||
return 1
|
|
||||||
else:
|
|
||||||
return max(numbers) + 1
|
|
||||||
|
|
||||||
def _get_links(self, link_to_self):
|
def _get_links(self, link_to_self):
|
||||||
links = []
|
links = []
|
||||||
@ -319,7 +320,9 @@ class Service(object):
|
|||||||
container_options = dict((k, self.options[k]) for k in DOCKER_CONFIG_KEYS if k in self.options)
|
container_options = dict((k, self.options[k]) for k in DOCKER_CONFIG_KEYS if k in self.options)
|
||||||
container_options.update(override_options)
|
container_options.update(override_options)
|
||||||
|
|
||||||
container_options['name'] = self.next_container_name(one_off)
|
container_options['name'] = self._next_container_name(
|
||||||
|
self.containers(stopped=True, one_off=one_off),
|
||||||
|
one_off)
|
||||||
|
|
||||||
# If a qualified hostname was given, split it into an
|
# If a qualified hostname was given, split it into an
|
||||||
# unqualified hostname and a domainname unless domainname
|
# unqualified hostname and a domainname unless domainname
|
||||||
@ -424,10 +427,10 @@ def is_valid_name(name, one_off=False):
|
|||||||
return match.group(3) is None
|
return match.group(3) is None
|
||||||
|
|
||||||
|
|
||||||
def parse_name(name, one_off=False):
|
def parse_name(name):
|
||||||
match = NAME_RE.match(name)
|
match = NAME_RE.match(name)
|
||||||
(project, service_name, _, suffix) = match.groups()
|
(project, service_name, _, suffix) = match.groups()
|
||||||
return (project, service_name, int(suffix))
|
return ServiceName(project, service_name, int(suffix))
|
||||||
|
|
||||||
|
|
||||||
def get_container_name(container):
|
def get_container_name(container):
|
||||||
|
@ -10,7 +10,6 @@ class DockerClientTestCase(unittest.TestCase):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
cls.client = Client(docker_url())
|
cls.client = Client(docker_url())
|
||||||
cls.client.pull('busybox', tag='latest')
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
for c in self.client.containers(all=True):
|
for c in self.client.containers(all=True):
|
||||||
|
@ -17,6 +17,10 @@ from fig.service import (
|
|||||||
|
|
||||||
|
|
||||||
class ServiceTest(unittest.TestCase):
|
class ServiceTest(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.mock_client = mock.create_autospec(docker.Client)
|
||||||
|
|
||||||
def test_name_validations(self):
|
def test_name_validations(self):
|
||||||
self.assertRaises(ConfigError, lambda: Service(name=''))
|
self.assertRaises(ConfigError, lambda: Service(name=''))
|
||||||
|
|
||||||
@ -70,10 +74,8 @@ class ServiceTest(unittest.TestCase):
|
|||||||
split_port("0.0.0.0:1000:2000:tcp")
|
split_port("0.0.0.0:1000:2000:tcp")
|
||||||
|
|
||||||
def test_split_domainname_none(self):
|
def test_split_domainname_none(self):
|
||||||
service = Service('foo',
|
service = Service('foo', hostname='name', client=self.mock_client)
|
||||||
hostname = 'name',
|
self.mock_client.containers.return_value = []
|
||||||
)
|
|
||||||
service.next_container_name = lambda x: 'foo'
|
|
||||||
opts = service._get_container_create_options({})
|
opts = service._get_container_create_options({})
|
||||||
self.assertEqual(opts['hostname'], 'name', 'hostname')
|
self.assertEqual(opts['hostname'], 'name', 'hostname')
|
||||||
self.assertFalse('domainname' in opts, 'domainname')
|
self.assertFalse('domainname' in opts, 'domainname')
|
||||||
@ -81,8 +83,8 @@ class ServiceTest(unittest.TestCase):
|
|||||||
def test_split_domainname_fqdn(self):
|
def test_split_domainname_fqdn(self):
|
||||||
service = Service('foo',
|
service = Service('foo',
|
||||||
hostname='name.domain.tld',
|
hostname='name.domain.tld',
|
||||||
)
|
client=self.mock_client)
|
||||||
service.next_container_name = lambda x: 'foo'
|
self.mock_client.containers.return_value = []
|
||||||
opts = service._get_container_create_options({})
|
opts = service._get_container_create_options({})
|
||||||
self.assertEqual(opts['hostname'], 'name', 'hostname')
|
self.assertEqual(opts['hostname'], 'name', 'hostname')
|
||||||
self.assertEqual(opts['domainname'], 'domain.tld', 'domainname')
|
self.assertEqual(opts['domainname'], 'domain.tld', 'domainname')
|
||||||
@ -91,8 +93,8 @@ class ServiceTest(unittest.TestCase):
|
|||||||
service = Service('foo',
|
service = Service('foo',
|
||||||
hostname='name',
|
hostname='name',
|
||||||
domainname='domain.tld',
|
domainname='domain.tld',
|
||||||
)
|
client=self.mock_client)
|
||||||
service.next_container_name = lambda x: 'foo'
|
self.mock_client.containers.return_value = []
|
||||||
opts = service._get_container_create_options({})
|
opts = service._get_container_create_options({})
|
||||||
self.assertEqual(opts['hostname'], 'name', 'hostname')
|
self.assertEqual(opts['hostname'], 'name', 'hostname')
|
||||||
self.assertEqual(opts['domainname'], 'domain.tld', 'domainname')
|
self.assertEqual(opts['domainname'], 'domain.tld', 'domainname')
|
||||||
@ -101,8 +103,8 @@ class ServiceTest(unittest.TestCase):
|
|||||||
service = Service('foo',
|
service = Service('foo',
|
||||||
hostname='name.sub',
|
hostname='name.sub',
|
||||||
domainname='domain.tld',
|
domainname='domain.tld',
|
||||||
)
|
client=self.mock_client)
|
||||||
service.next_container_name = lambda x: 'foo'
|
self.mock_client.containers.return_value = []
|
||||||
opts = service._get_container_create_options({})
|
opts = service._get_container_create_options({})
|
||||||
self.assertEqual(opts['hostname'], 'name.sub', 'hostname')
|
self.assertEqual(opts['hostname'], 'name.sub', 'hostname')
|
||||||
self.assertEqual(opts['domainname'], 'domain.tld', 'domainname')
|
self.assertEqual(opts['domainname'], 'domain.tld', 'domainname')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user