Merge pull request #1488 from dnephin/config_from_stdin

Support reading config from stdin
This commit is contained in:
Aanand Prasad 2015-07-03 09:03:40 +01:00
commit db7e5124f3
10 changed files with 197 additions and 147 deletions

View file

@ -36,7 +36,7 @@ class CLITestCase(DockerClientTestCase):
if hasattr(self, '_project'):
return self._project
return self.command.get_project(self.command.get_config_path())
return self.command.get_project()
def test_help(self):
old_base_dir = self.command.base_dir

View file

@ -7,6 +7,10 @@ from compose.container import Container
from .testcases import DockerClientTestCase
def build_service_dicts(service_config):
return config.load(config.ConfigDetails(service_config, 'working_dir', None))
class ProjectTest(DockerClientTestCase):
def test_containers(self):
@ -32,7 +36,7 @@ class ProjectTest(DockerClientTestCase):
['composetest_web_1'])
def test_volumes_from_service(self):
service_dicts = config.from_dictionary({
service_dicts = build_service_dicts({
'data': {
'image': 'busybox:latest',
'volumes': ['/var/data'],
@ -41,7 +45,7 @@ class ProjectTest(DockerClientTestCase):
'image': 'busybox:latest',
'volumes_from': ['data'],
},
}, working_dir='.')
})
project = Project.from_dicts(
name='composetest',
service_dicts=service_dicts,
@ -61,7 +65,7 @@ class ProjectTest(DockerClientTestCase):
)
project = Project.from_dicts(
name='composetest',
service_dicts=config.from_dictionary({
service_dicts=build_service_dicts({
'db': {
'image': 'busybox:latest',
'volumes_from': ['composetest_data_container'],
@ -75,7 +79,7 @@ class ProjectTest(DockerClientTestCase):
def test_net_from_service(self):
project = Project.from_dicts(
name='composetest',
service_dicts=config.from_dictionary({
service_dicts=build_service_dicts({
'net': {
'image': 'busybox:latest',
'command': ["top"]
@ -107,7 +111,7 @@ class ProjectTest(DockerClientTestCase):
project = Project.from_dicts(
name='composetest',
service_dicts=config.from_dictionary({
service_dicts=build_service_dicts({
'web': {
'image': 'busybox:latest',
'net': 'container:composetest_net_container'
@ -274,7 +278,7 @@ class ProjectTest(DockerClientTestCase):
def test_project_up_starts_depends(self):
project = Project.from_dicts(
name='composetest',
service_dicts=config.from_dictionary({
service_dicts=build_service_dicts({
'console': {
'image': 'busybox:latest',
'command': ["top"],
@ -309,7 +313,7 @@ class ProjectTest(DockerClientTestCase):
def test_project_up_with_no_deps(self):
project = Project.from_dicts(
name='composetest',
service_dicts=config.from_dictionary({
service_dicts=build_service_dicts({
'console': {
'image': 'busybox:latest',
'command': ["top"],

View file

@ -23,7 +23,7 @@ class ProjectTestCase(DockerClientTestCase):
return Project.from_dicts(
name='composetest',
client=self.client,
service_dicts=config.from_dictionary(cfg),
service_dicts=config.load(config.ConfigDetails(cfg, 'working_dir', None))
)

View file

@ -2,17 +2,14 @@ from __future__ import unicode_literals
from __future__ import absolute_import
import logging
import os
import tempfile
import shutil
from .. import unittest
import docker
import mock
from compose.cli import main
from compose.cli.main import TopLevelCommand
from compose.cli.docopt_command import NoSuchCommand
from compose.cli.errors import ComposeFileNotFound
from compose.cli.main import TopLevelCommand
from compose.service import Service
@ -23,7 +20,7 @@ class CLITestCase(unittest.TestCase):
try:
os.chdir('tests/fixtures/simple-composefile')
command = TopLevelCommand()
project_name = command.get_project_name(command.get_config_path())
project_name = command.get_project_name('.')
self.assertEquals('simplecomposefile', project_name)
finally:
os.chdir(cwd)
@ -31,13 +28,13 @@ class CLITestCase(unittest.TestCase):
def test_project_name_with_explicit_base_dir(self):
command = TopLevelCommand()
command.base_dir = 'tests/fixtures/simple-composefile'
project_name = command.get_project_name(command.get_config_path())
project_name = command.get_project_name(command.base_dir)
self.assertEquals('simplecomposefile', project_name)
def test_project_name_with_explicit_uppercase_base_dir(self):
command = TopLevelCommand()
command.base_dir = 'tests/fixtures/UpperCaseDir'
project_name = command.get_project_name(command.get_config_path())
project_name = command.get_project_name(command.base_dir)
self.assertEquals('uppercasedir', project_name)
def test_project_name_with_explicit_project_name(self):
@ -62,37 +59,10 @@ class CLITestCase(unittest.TestCase):
project_name = command.get_project_name(None)
self.assertEquals(project_name, name)
def test_filename_check(self):
files = [
'docker-compose.yml',
'docker-compose.yaml',
'fig.yml',
'fig.yaml',
]
"""Test with files placed in the basedir"""
self.assertEqual('docker-compose.yml', get_config_filename_for_files(files[0:]))
self.assertEqual('docker-compose.yaml', get_config_filename_for_files(files[1:]))
self.assertEqual('fig.yml', get_config_filename_for_files(files[2:]))
self.assertEqual('fig.yaml', get_config_filename_for_files(files[3:]))
self.assertRaises(ComposeFileNotFound, lambda: get_config_filename_for_files([]))
"""Test with files placed in the subdir"""
def get_config_filename_for_files_in_subdir(files):
return get_config_filename_for_files(files, subdir=True)
self.assertEqual('docker-compose.yml', get_config_filename_for_files_in_subdir(files[0:]))
self.assertEqual('docker-compose.yaml', get_config_filename_for_files_in_subdir(files[1:]))
self.assertEqual('fig.yml', get_config_filename_for_files_in_subdir(files[2:]))
self.assertEqual('fig.yaml', get_config_filename_for_files_in_subdir(files[3:]))
self.assertRaises(ComposeFileNotFound, lambda: get_config_filename_for_files_in_subdir([]))
def test_get_project(self):
command = TopLevelCommand()
command.base_dir = 'tests/fixtures/longer-filename-composefile'
project = command.get_project(command.get_config_path())
project = command.get_project()
self.assertEqual(project.name, 'longerfilenamecomposefile')
self.assertTrue(project.client)
self.assertTrue(project.services)
@ -201,23 +171,3 @@ class CLITestCase(unittest.TestCase):
})
_, _, call_kwargs = mock_client.create_container.mock_calls[0]
self.assertFalse('RestartPolicy' in call_kwargs['host_config'])
def get_config_filename_for_files(filenames, subdir=None):
project_dir = tempfile.mkdtemp()
try:
make_files(project_dir, filenames)
command = TopLevelCommand()
if subdir:
command.base_dir = tempfile.mkdtemp(dir=project_dir)
else:
command.base_dir = project_dir
return os.path.basename(command.get_config_path())
finally:
shutil.rmtree(project_dir)
def make_files(dirname, filenames):
for fname in filenames:
with open(os.path.join(dirname, fname), 'w') as f:
f.write('')

View file

@ -1,16 +1,24 @@
import os
import mock
import os
import shutil
import tempfile
from .. import unittest
from compose import config
class ConfigTest(unittest.TestCase):
def test_from_dictionary(self):
service_dicts = config.from_dictionary({
'foo': {'image': 'busybox'},
'bar': {'environment': ['FOO=1']},
})
def test_load(self):
service_dicts = config.load(
config.ConfigDetails(
{
'foo': {'image': 'busybox'},
'bar': {'environment': ['FOO=1']},
},
'working_dir',
'filename.yml'
)
)
self.assertEqual(
sorted(service_dicts, key=lambda d: d['name']),
@ -26,11 +34,15 @@ class ConfigTest(unittest.TestCase):
])
)
def test_from_dictionary_throws_error_when_not_dict(self):
def test_load_throws_error_when_not_dict(self):
with self.assertRaises(config.ConfigurationError):
config.from_dictionary({
'web': 'busybox:latest',
})
config.load(
config.ConfigDetails(
{'web': 'busybox:latest'},
'working_dir',
'filename.yml'
)
)
def test_config_validation(self):
self.assertRaises(
@ -354,9 +366,13 @@ class EnvTest(unittest.TestCase):
self.assertEqual(set(service_dict['volumes']), set(['/opt/tmp:/opt/host/tmp']))
def load_from_filename(filename):
return config.load(config.find('.', filename))
class ExtendsTest(unittest.TestCase):
def test_extends(self):
service_dicts = config.load('tests/fixtures/extends/docker-compose.yml')
service_dicts = load_from_filename('tests/fixtures/extends/docker-compose.yml')
service_dicts = sorted(
service_dicts,
@ -383,7 +399,7 @@ class ExtendsTest(unittest.TestCase):
])
def test_nested(self):
service_dicts = config.load('tests/fixtures/extends/nested.yml')
service_dicts = load_from_filename('tests/fixtures/extends/nested.yml')
self.assertEqual(service_dicts, [
{
@ -399,7 +415,7 @@ class ExtendsTest(unittest.TestCase):
def test_circular(self):
try:
config.load('tests/fixtures/extends/circle-1.yml')
load_from_filename('tests/fixtures/extends/circle-1.yml')
raise Exception("Expected config.CircularReference to be raised")
except config.CircularReference as e:
self.assertEqual(
@ -464,7 +480,7 @@ class ExtendsTest(unittest.TestCase):
print load_config()
def test_volume_path(self):
dicts = config.load('tests/fixtures/volume-path/docker-compose.yml')
dicts = load_from_filename('tests/fixtures/volume-path/docker-compose.yml')
paths = [
'%s:/foo' % os.path.abspath('tests/fixtures/volume-path/common/foo'),
@ -474,7 +490,7 @@ class ExtendsTest(unittest.TestCase):
self.assertEqual(set(dicts[0]['volumes']), set(paths))
def test_parent_build_path_dne(self):
child = config.load('tests/fixtures/extends/nonexistent-path-child.yml')
child = load_from_filename('tests/fixtures/extends/nonexistent-path-child.yml')
self.assertEqual(child, [
{
@ -494,14 +510,16 @@ class BuildPathTest(unittest.TestCase):
self.abs_context_path = os.path.join(os.getcwd(), 'tests/fixtures/build-ctx')
def test_nonexistent_path(self):
options = {'build': 'nonexistent.path'}
self.assertRaises(
config.ConfigurationError,
lambda: config.from_dictionary({
'foo': options,
'working_dir': 'tests/fixtures/build-path'
})
)
with self.assertRaises(config.ConfigurationError):
config.load(
config.ConfigDetails(
{
'foo': {'build': 'nonexistent.path'},
},
'working_dir',
'filename.yml'
)
)
def test_relative_path(self):
relative_build_path = '../build-ctx/'
@ -521,5 +539,56 @@ class BuildPathTest(unittest.TestCase):
self.assertEquals(service_dict['build'], self.abs_context_path)
def test_from_file(self):
service_dict = config.load('tests/fixtures/build-path/docker-compose.yml')
service_dict = load_from_filename('tests/fixtures/build-path/docker-compose.yml')
self.assertEquals(service_dict, [{'name': 'foo', 'build': self.abs_context_path}])
class GetConfigPathTestCase(unittest.TestCase):
files = [
'docker-compose.yml',
'docker-compose.yaml',
'fig.yml',
'fig.yaml',
]
def test_get_config_path_default_file_in_basedir(self):
files = self.files
self.assertEqual('docker-compose.yml', get_config_filename_for_files(files[0:]))
self.assertEqual('docker-compose.yaml', get_config_filename_for_files(files[1:]))
self.assertEqual('fig.yml', get_config_filename_for_files(files[2:]))
self.assertEqual('fig.yaml', get_config_filename_for_files(files[3:]))
with self.assertRaises(config.ComposeFileNotFound):
get_config_filename_for_files([])
def test_get_config_path_default_file_in_parent_dir(self):
"""Test with files placed in the subdir"""
files = self.files
def get_config_in_subdir(files):
return get_config_filename_for_files(files, subdir=True)
self.assertEqual('docker-compose.yml', get_config_in_subdir(files[0:]))
self.assertEqual('docker-compose.yaml', get_config_in_subdir(files[1:]))
self.assertEqual('fig.yml', get_config_in_subdir(files[2:]))
self.assertEqual('fig.yaml', get_config_in_subdir(files[3:]))
with self.assertRaises(config.ComposeFileNotFound):
get_config_in_subdir([])
def get_config_filename_for_files(filenames, subdir=None):
def make_files(dirname, filenames):
for fname in filenames:
with open(os.path.join(dirname, fname), 'w') as f:
f.write('')
project_dir = tempfile.mkdtemp()
try:
make_files(project_dir, filenames)
if subdir:
base_dir = tempfile.mkdtemp(dir=project_dir)
else:
base_dir = project_dir
return os.path.basename(config.get_config_path(base_dir))
finally:
shutil.rmtree(project_dir)

View file

@ -3,7 +3,6 @@ from .. import unittest
from compose.service import Service
from compose.project import Project
from compose.container import Container
from compose import config
import mock
import docker
@ -51,14 +50,16 @@ class ProjectTest(unittest.TestCase):
self.assertEqual(project.services[2].name, 'web')
def test_from_config(self):
dicts = config.from_dictionary({
'web': {
dicts = [
{
'name': 'web',
'image': 'busybox:latest',
},
'db': {
{
'name': 'db',
'image': 'busybox:latest',
},
})
]
project = Project.from_dicts('composetest', dicts, None)
self.assertEqual(len(project.services), 2)
self.assertEqual(project.get_service('web').name, 'web')