Make volumes_from and net containers first class dependencies and
assure that starting order is correct. Added supporting unit and integration tests as well. Signed-off-by: Gil Clark <gilclark1@gmail.com>
This commit is contained in:
parent
9e9a66f0f8
commit
95f4e2c7c3
6 changed files with 429 additions and 41 deletions
|
|
@ -44,6 +44,63 @@ class ProjectTest(DockerClientTestCase):
|
|||
db = project.get_service('db')
|
||||
self.assertEqual(db.volumes_from, [data_container])
|
||||
|
||||
project.kill()
|
||||
project.remove_stopped()
|
||||
|
||||
def test_net_from_service(self):
|
||||
project = Project.from_config(
|
||||
name='composetest',
|
||||
config={
|
||||
'net': {
|
||||
'image': 'busybox:latest',
|
||||
'command': ["/bin/sleep", "300"]
|
||||
},
|
||||
'web': {
|
||||
'image': 'busybox:latest',
|
||||
'net': 'container:net',
|
||||
'command': ["/bin/sleep", "300"]
|
||||
},
|
||||
},
|
||||
client=self.client,
|
||||
)
|
||||
|
||||
project.up()
|
||||
|
||||
web = project.get_service('web')
|
||||
net = project.get_service('net')
|
||||
self.assertEqual(web._get_net(), 'container:'+net.containers()[0].id)
|
||||
|
||||
project.kill()
|
||||
project.remove_stopped()
|
||||
|
||||
def test_net_from_container(self):
|
||||
net_container = Container.create(
|
||||
self.client,
|
||||
image='busybox:latest',
|
||||
name='composetest_net_container',
|
||||
command='/bin/sleep 300'
|
||||
)
|
||||
net_container.start()
|
||||
|
||||
project = Project.from_config(
|
||||
name='composetest',
|
||||
config={
|
||||
'web': {
|
||||
'image': 'busybox:latest',
|
||||
'net': 'container:composetest_net_container'
|
||||
},
|
||||
},
|
||||
client=self.client,
|
||||
)
|
||||
|
||||
project.up()
|
||||
|
||||
web = project.get_service('web')
|
||||
self.assertEqual(web._get_net(), 'container:'+net_container.id)
|
||||
|
||||
project.kill()
|
||||
project.remove_stopped()
|
||||
|
||||
def test_start_stop_kill_remove(self):
|
||||
web = self.create_service('web')
|
||||
db = self.create_service('db')
|
||||
|
|
@ -199,20 +256,86 @@ class ProjectTest(DockerClientTestCase):
|
|||
project.kill()
|
||||
project.remove_stopped()
|
||||
|
||||
def test_project_up_with_no_deps(self):
|
||||
console = self.create_service('console')
|
||||
db = self.create_service('db', volumes=['/var/db'])
|
||||
web = self.create_service('web', links=[(db, 'db')])
|
||||
|
||||
project = Project('composetest', [web, db, console], self.client)
|
||||
def test_project_up_starts_depends(self):
|
||||
project = Project.from_config(
|
||||
name='composetest',
|
||||
config={
|
||||
'console': {
|
||||
'image': 'busybox:latest',
|
||||
'command': ["/bin/sleep", "300"],
|
||||
},
|
||||
'net' : {
|
||||
'image': 'busybox:latest',
|
||||
'command': ["/bin/sleep", "300"]
|
||||
},
|
||||
'app': {
|
||||
'image': 'busybox:latest',
|
||||
'command': ["/bin/sleep", "300"],
|
||||
'net': 'container:net'
|
||||
},
|
||||
'web': {
|
||||
'image': 'busybox:latest',
|
||||
'command': ["/bin/sleep", "300"],
|
||||
'net': 'container:net',
|
||||
'links': ['app']
|
||||
},
|
||||
},
|
||||
client=self.client,
|
||||
)
|
||||
project.start()
|
||||
self.assertEqual(len(project.containers()), 0)
|
||||
|
||||
project.up(['web'], start_links=False)
|
||||
self.assertEqual(len(project.containers()), 1)
|
||||
self.assertEqual(len(web.containers()), 1)
|
||||
self.assertEqual(len(db.containers()), 0)
|
||||
self.assertEqual(len(console.containers()), 0)
|
||||
project.up(['web'])
|
||||
self.assertEqual(len(project.containers()), 3)
|
||||
self.assertEqual(len(project.get_service('web').containers()), 1)
|
||||
self.assertEqual(len(project.get_service('app').containers()), 1)
|
||||
self.assertEqual(len(project.get_service('net').containers()), 1)
|
||||
self.assertEqual(len(project.get_service('console').containers()), 0)
|
||||
|
||||
project.kill()
|
||||
project.remove_stopped()
|
||||
|
||||
def test_project_up_with_no_deps(self):
|
||||
project = Project.from_config(
|
||||
name='composetest',
|
||||
config={
|
||||
'console': {
|
||||
'image': 'busybox:latest',
|
||||
'command': ["/bin/sleep", "300"],
|
||||
},
|
||||
'net' : {
|
||||
'image': 'busybox:latest',
|
||||
'command': ["/bin/sleep", "300"]
|
||||
},
|
||||
'vol': {
|
||||
'image': 'busybox:latest',
|
||||
'command': ["/bin/sleep", "300"],
|
||||
'volumes': ["/tmp"]
|
||||
},
|
||||
'app': {
|
||||
'image': 'busybox:latest',
|
||||
'command': ["/bin/sleep", "300"],
|
||||
'net': 'container:net'
|
||||
},
|
||||
'web': {
|
||||
'image': 'busybox:latest',
|
||||
'command': ["/bin/sleep", "300"],
|
||||
'net': 'container:net',
|
||||
'links': ['app'],
|
||||
'volumes_from': ['vol']
|
||||
},
|
||||
},
|
||||
client=self.client,
|
||||
)
|
||||
project.start()
|
||||
self.assertEqual(len(project.containers()), 0)
|
||||
|
||||
project.up(['web'], start_deps=False)
|
||||
self.assertEqual(len(project.containers(stopped=True)), 2)
|
||||
self.assertEqual(len(project.get_service('web').containers()), 1)
|
||||
self.assertEqual(len(project.get_service('vol').containers(stopped=True)), 1)
|
||||
self.assertEqual(len(project.get_service('net').containers()), 0)
|
||||
self.assertEqual(len(project.get_service('console').containers()), 0)
|
||||
|
||||
project.kill()
|
||||
project.remove_stopped()
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ from __future__ import unicode_literals
|
|||
from .. import unittest
|
||||
from compose.service import Service
|
||||
from compose.project import Project, ConfigurationError
|
||||
from compose.container import Container
|
||||
|
||||
import mock
|
||||
import docker
|
||||
|
||||
class ProjectTest(unittest.TestCase):
|
||||
def test_from_dict(self):
|
||||
|
|
@ -120,7 +124,7 @@ class ProjectTest(unittest.TestCase):
|
|||
)
|
||||
project = Project('test', [web, db, cache, console], None)
|
||||
self.assertEqual(
|
||||
project.get_services(['console'], include_links=True),
|
||||
project.get_services(['console'], include_deps=True),
|
||||
[db, web, console]
|
||||
)
|
||||
|
||||
|
|
@ -136,6 +140,105 @@ class ProjectTest(unittest.TestCase):
|
|||
)
|
||||
project = Project('test', [web, db], None)
|
||||
self.assertEqual(
|
||||
project.get_services(['web', 'db'], include_links=True),
|
||||
project.get_services(['web', 'db'], include_deps=True),
|
||||
[db, web]
|
||||
)
|
||||
|
||||
def test_use_volumes_from_container(self):
|
||||
container_id = 'aabbccddee'
|
||||
container_dict = dict(Name='aaa', Id=container_id)
|
||||
mock_client = mock.create_autospec(docker.Client)
|
||||
mock_client.inspect_container.return_value = container_dict
|
||||
project = Project.from_dicts('test', [
|
||||
{
|
||||
'name': 'test',
|
||||
'image': 'busybox:latest',
|
||||
'volumes_from': ['aaa']
|
||||
}
|
||||
], mock_client)
|
||||
self.assertEqual(project.get_service('test')._get_volumes_from(), [container_id])
|
||||
|
||||
def test_use_volumes_from_service_no_container(self):
|
||||
container_name = 'test_vol_1'
|
||||
mock_client = mock.create_autospec(docker.Client)
|
||||
mock_client.containers.return_value = [
|
||||
{
|
||||
"Name": container_name,
|
||||
"Names": [container_name],
|
||||
"Id": container_name,
|
||||
"Image": 'busybox:latest'
|
||||
}
|
||||
]
|
||||
project = Project.from_dicts('test', [
|
||||
{
|
||||
'name': 'vol',
|
||||
'image': 'busybox:latest'
|
||||
},
|
||||
{
|
||||
'name': 'test',
|
||||
'image': 'busybox:latest',
|
||||
'volumes_from': ['vol']
|
||||
}
|
||||
], mock_client)
|
||||
self.assertEqual(project.get_service('test')._get_volumes_from(), [container_name])
|
||||
|
||||
@mock.patch.object(Service, 'containers')
|
||||
def test_use_volumes_from_service_container(self, mock_return):
|
||||
container_ids = ['aabbccddee', '12345']
|
||||
mock_return.return_value = [
|
||||
mock.Mock(id=container_id, spec=Container)
|
||||
for container_id in container_ids]
|
||||
|
||||
project = Project.from_dicts('test', [
|
||||
{
|
||||
'name': 'vol',
|
||||
'image': 'busybox:latest'
|
||||
},
|
||||
{
|
||||
'name': 'test',
|
||||
'image': 'busybox:latest',
|
||||
'volumes_from': ['vol']
|
||||
}
|
||||
], None)
|
||||
self.assertEqual(project.get_service('test')._get_volumes_from(), container_ids)
|
||||
|
||||
def test_use_net_from_container(self):
|
||||
container_id = 'aabbccddee'
|
||||
container_dict = dict(Name='aaa', Id=container_id)
|
||||
mock_client = mock.create_autospec(docker.Client)
|
||||
mock_client.inspect_container.return_value = container_dict
|
||||
project = Project.from_dicts('test', [
|
||||
{
|
||||
'name': 'test',
|
||||
'image': 'busybox:latest',
|
||||
'net': 'container:aaa'
|
||||
}
|
||||
], mock_client)
|
||||
service = project.get_service('test')
|
||||
self.assertEqual(service._get_net(), 'container:'+container_id)
|
||||
|
||||
def test_use_net_from_service(self):
|
||||
container_name = 'test_aaa_1'
|
||||
mock_client = mock.create_autospec(docker.Client)
|
||||
mock_client.containers.return_value = [
|
||||
{
|
||||
"Name": container_name,
|
||||
"Names": [container_name],
|
||||
"Id": container_name,
|
||||
"Image": 'busybox:latest'
|
||||
}
|
||||
]
|
||||
project = Project.from_dicts('test', [
|
||||
{
|
||||
'name': 'aaa',
|
||||
'image': 'busybox:latest'
|
||||
},
|
||||
{
|
||||
'name': 'test',
|
||||
'image': 'busybox:latest',
|
||||
'net': 'container:aaa'
|
||||
}
|
||||
], mock_client)
|
||||
|
||||
service = project.get_service('test')
|
||||
self.assertEqual(service._get_net(), 'container:'+container_name)
|
||||
|
|
|
|||
|
|
@ -65,6 +65,95 @@ class SortServiceTest(unittest.TestCase):
|
|||
self.assertEqual(sorted_services[1]['name'], 'parent')
|
||||
self.assertEqual(sorted_services[2]['name'], 'grandparent')
|
||||
|
||||
def test_sort_service_dicts_4(self):
|
||||
services = [
|
||||
{
|
||||
'name': 'child'
|
||||
},
|
||||
{
|
||||
'name': 'parent',
|
||||
'volumes_from': ['child']
|
||||
},
|
||||
{
|
||||
'links': ['parent'],
|
||||
'name': 'grandparent'
|
||||
},
|
||||
]
|
||||
|
||||
sorted_services = sort_service_dicts(services)
|
||||
self.assertEqual(len(sorted_services), 3)
|
||||
self.assertEqual(sorted_services[0]['name'], 'child')
|
||||
self.assertEqual(sorted_services[1]['name'], 'parent')
|
||||
self.assertEqual(sorted_services[2]['name'], 'grandparent')
|
||||
|
||||
def test_sort_service_dicts_5(self):
|
||||
services = [
|
||||
{
|
||||
'links': ['parent'],
|
||||
'name': 'grandparent'
|
||||
},
|
||||
{
|
||||
'name': 'parent',
|
||||
'net': 'container:child'
|
||||
},
|
||||
{
|
||||
'name': 'child'
|
||||
}
|
||||
]
|
||||
|
||||
sorted_services = sort_service_dicts(services)
|
||||
self.assertEqual(len(sorted_services), 3)
|
||||
self.assertEqual(sorted_services[0]['name'], 'child')
|
||||
self.assertEqual(sorted_services[1]['name'], 'parent')
|
||||
self.assertEqual(sorted_services[2]['name'], 'grandparent')
|
||||
|
||||
def test_sort_service_dicts_6(self):
|
||||
services = [
|
||||
{
|
||||
'links': ['parent'],
|
||||
'name': 'grandparent'
|
||||
},
|
||||
{
|
||||
'name': 'parent',
|
||||
'volumes_from': ['child']
|
||||
},
|
||||
{
|
||||
'name': 'child'
|
||||
}
|
||||
]
|
||||
|
||||
sorted_services = sort_service_dicts(services)
|
||||
self.assertEqual(len(sorted_services), 3)
|
||||
self.assertEqual(sorted_services[0]['name'], 'child')
|
||||
self.assertEqual(sorted_services[1]['name'], 'parent')
|
||||
self.assertEqual(sorted_services[2]['name'], 'grandparent')
|
||||
|
||||
def test_sort_service_dicts_7(self):
|
||||
services = [
|
||||
{
|
||||
'net': 'container:three',
|
||||
'name': 'four'
|
||||
},
|
||||
{
|
||||
'links': ['two'],
|
||||
'name': 'three'
|
||||
},
|
||||
{
|
||||
'name': 'two',
|
||||
'volumes_from': ['one']
|
||||
},
|
||||
{
|
||||
'name': 'one'
|
||||
}
|
||||
]
|
||||
|
||||
sorted_services = sort_service_dicts(services)
|
||||
self.assertEqual(len(sorted_services), 4)
|
||||
self.assertEqual(sorted_services[0]['name'], 'one')
|
||||
self.assertEqual(sorted_services[1]['name'], 'two')
|
||||
self.assertEqual(sorted_services[2]['name'], 'three')
|
||||
self.assertEqual(sorted_services[3]['name'], 'four')
|
||||
|
||||
def test_sort_service_dicts_circular_imports(self):
|
||||
services = [
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue