|
@@ -103,8 +103,15 @@ class CLITestCase(DockerClientTestCase):
|
|
|
if self.base_dir:
|
|
if self.base_dir:
|
|
|
self.project.kill()
|
|
self.project.kill()
|
|
|
self.project.remove_stopped()
|
|
self.project.remove_stopped()
|
|
|
|
|
+
|
|
|
for container in self.project.containers(stopped=True, one_off=True):
|
|
for container in self.project.containers(stopped=True, one_off=True):
|
|
|
container.remove(force=True)
|
|
container.remove(force=True)
|
|
|
|
|
+
|
|
|
|
|
+ networks = self.client.networks()
|
|
|
|
|
+ for n in networks:
|
|
|
|
|
+ if n['Name'].startswith('{}_'.format(self.project.name)):
|
|
|
|
|
+ self.client.remove_network(n['Name'])
|
|
|
|
|
+
|
|
|
super(CLITestCase, self).tearDown()
|
|
super(CLITestCase, self).tearDown()
|
|
|
|
|
|
|
|
@property
|
|
@property
|
|
@@ -119,6 +126,20 @@ class CLITestCase(DockerClientTestCase):
|
|
|
proc = start_process(self.base_dir, project_options + options)
|
|
proc = start_process(self.base_dir, project_options + options)
|
|
|
return wait_on_process(proc, returncode=returncode)
|
|
return wait_on_process(proc, returncode=returncode)
|
|
|
|
|
|
|
|
|
|
+ def execute(self, container, cmd):
|
|
|
|
|
+ # Remove once Hijack and CloseNotifier sign a peace treaty
|
|
|
|
|
+ self.client.close()
|
|
|
|
|
+ exc = self.client.exec_create(container.id, cmd)
|
|
|
|
|
+ self.client.exec_start(exc)
|
|
|
|
|
+ return self.client.exec_inspect(exc)['ExitCode']
|
|
|
|
|
+
|
|
|
|
|
+ def lookup(self, container, service_name):
|
|
|
|
|
+ exit_code = self.execute(container, [
|
|
|
|
|
+ "nslookup",
|
|
|
|
|
+ "{}_{}_1".format(self.project.name, service_name)
|
|
|
|
|
+ ])
|
|
|
|
|
+ return exit_code == 0
|
|
|
|
|
+
|
|
|
def test_help(self):
|
|
def test_help(self):
|
|
|
self.base_dir = 'tests/fixtures/no-composefile'
|
|
self.base_dir = 'tests/fixtures/no-composefile'
|
|
|
result = self.dispatch(['help', 'up'], returncode=1)
|
|
result = self.dispatch(['help', 'up'], returncode=1)
|
|
@@ -350,43 +371,127 @@ class CLITestCase(DockerClientTestCase):
|
|
|
assert 'simple_1 | simple' in result.stdout
|
|
assert 'simple_1 | simple' in result.stdout
|
|
|
assert 'another_1 | another' in result.stdout
|
|
assert 'another_1 | another' in result.stdout
|
|
|
|
|
|
|
|
- def test_up_without_networking(self):
|
|
|
|
|
- self.base_dir = 'tests/fixtures/links-composefile'
|
|
|
|
|
- self.dispatch(['up', '-d'], None)
|
|
|
|
|
-
|
|
|
|
|
- networks = self.client.networks(names=[self.project.default_network_name])
|
|
|
|
|
- self.assertEqual(len(networks), 0)
|
|
|
|
|
-
|
|
|
|
|
- for service in self.project.get_services():
|
|
|
|
|
- containers = service.containers()
|
|
|
|
|
- self.assertEqual(len(containers), 1)
|
|
|
|
|
- self.assertNotEqual(containers[0].get('Config.Hostname'), service.name)
|
|
|
|
|
-
|
|
|
|
|
- web_container = self.project.get_service('web').containers()[0]
|
|
|
|
|
- self.assertTrue(web_container.get('HostConfig.Links'))
|
|
|
|
|
-
|
|
|
|
|
- def test_up_with_networking(self):
|
|
|
|
|
|
|
+ def test_up(self):
|
|
|
self.base_dir = 'tests/fixtures/v2-simple'
|
|
self.base_dir = 'tests/fixtures/v2-simple'
|
|
|
self.dispatch(['up', '-d'], None)
|
|
self.dispatch(['up', '-d'], None)
|
|
|
|
|
|
|
|
services = self.project.get_services()
|
|
services = self.project.get_services()
|
|
|
|
|
|
|
|
- networks = self.client.networks(names=[self.project.default_network_name])
|
|
|
|
|
- for n in networks:
|
|
|
|
|
- self.addCleanup(self.client.remove_network, n['Id'])
|
|
|
|
|
|
|
+ networks = self.client.networks(names=[self.project.default_network.full_name])
|
|
|
self.assertEqual(len(networks), 1)
|
|
self.assertEqual(len(networks), 1)
|
|
|
self.assertEqual(networks[0]['Driver'], 'bridge')
|
|
self.assertEqual(networks[0]['Driver'], 'bridge')
|
|
|
|
|
|
|
|
network = self.client.inspect_network(networks[0]['Id'])
|
|
network = self.client.inspect_network(networks[0]['Id'])
|
|
|
- self.assertEqual(len(network['Containers']), len(services))
|
|
|
|
|
|
|
|
|
|
for service in services:
|
|
for service in services:
|
|
|
containers = service.containers()
|
|
containers = service.containers()
|
|
|
self.assertEqual(len(containers), 1)
|
|
self.assertEqual(len(containers), 1)
|
|
|
- self.assertIn(containers[0].id, network['Containers'])
|
|
|
|
|
|
|
|
|
|
- web_container = self.project.get_service('simple').containers()[0]
|
|
|
|
|
- self.assertFalse(web_container.get('HostConfig.Links'))
|
|
|
|
|
|
|
+ container = containers[0]
|
|
|
|
|
+ self.assertIn(container.id, network['Containers'])
|
|
|
|
|
+
|
|
|
|
|
+ networks = list(container.get('NetworkSettings.Networks'))
|
|
|
|
|
+ self.assertEqual(networks, [network['Name']])
|
|
|
|
|
+
|
|
|
|
|
+ def test_up_with_networks(self):
|
|
|
|
|
+ self.base_dir = 'tests/fixtures/networks'
|
|
|
|
|
+ self.dispatch(['up', '-d'], None)
|
|
|
|
|
+
|
|
|
|
|
+ back_name = '{}_back'.format(self.project.name)
|
|
|
|
|
+ front_name = '{}_front'.format(self.project.name)
|
|
|
|
|
+
|
|
|
|
|
+ networks = [
|
|
|
|
|
+ n for n in self.client.networks()
|
|
|
|
|
+ if n['Name'].startswith('{}_'.format(self.project.name))
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ # Two networks were created: back and front
|
|
|
|
|
+ assert sorted(n['Name'] for n in networks) == [back_name, front_name]
|
|
|
|
|
+
|
|
|
|
|
+ back_network = [n for n in networks if n['Name'] == back_name][0]
|
|
|
|
|
+ front_network = [n for n in networks if n['Name'] == front_name][0]
|
|
|
|
|
+
|
|
|
|
|
+ web_container = self.project.get_service('web').containers()[0]
|
|
|
|
|
+ app_container = self.project.get_service('app').containers()[0]
|
|
|
|
|
+ db_container = self.project.get_service('db').containers()[0]
|
|
|
|
|
+
|
|
|
|
|
+ # db and app joined the back network
|
|
|
|
|
+ assert sorted(back_network['Containers']) == sorted([db_container.id, app_container.id])
|
|
|
|
|
+
|
|
|
|
|
+ # web and app joined the front network
|
|
|
|
|
+ assert sorted(front_network['Containers']) == sorted([web_container.id, app_container.id])
|
|
|
|
|
+
|
|
|
|
|
+ # web can see app but not db
|
|
|
|
|
+ assert self.lookup(web_container, "app")
|
|
|
|
|
+ assert not self.lookup(web_container, "db")
|
|
|
|
|
+
|
|
|
|
|
+ # app can see db
|
|
|
|
|
+ assert self.lookup(app_container, "db")
|
|
|
|
|
+
|
|
|
|
|
+ def test_up_missing_network(self):
|
|
|
|
|
+ self.base_dir = 'tests/fixtures/networks'
|
|
|
|
|
+
|
|
|
|
|
+ result = self.dispatch(
|
|
|
|
|
+ ['-f', 'missing-network.yml', 'up', '-d'],
|
|
|
|
|
+ returncode=1)
|
|
|
|
|
+
|
|
|
|
|
+ assert 'Service "web" uses an undefined network "foo"' in result.stderr
|
|
|
|
|
+
|
|
|
|
|
+ def test_up_predefined_networks(self):
|
|
|
|
|
+ filename = 'predefined-networks.yml'
|
|
|
|
|
+
|
|
|
|
|
+ self.base_dir = 'tests/fixtures/networks'
|
|
|
|
|
+ self._project = get_project(self.base_dir, [filename])
|
|
|
|
|
+
|
|
|
|
|
+ self.dispatch(['-f', filename, 'up', '-d'], None)
|
|
|
|
|
+
|
|
|
|
|
+ networks = [
|
|
|
|
|
+ n for n in self.client.networks()
|
|
|
|
|
+ if n['Name'].startswith('{}_'.format(self.project.name))
|
|
|
|
|
+ ]
|
|
|
|
|
+ assert not networks
|
|
|
|
|
+
|
|
|
|
|
+ for name in ['bridge', 'host', 'none']:
|
|
|
|
|
+ container = self.project.get_service(name).containers()[0]
|
|
|
|
|
+ assert list(container.get('NetworkSettings.Networks')) == [name]
|
|
|
|
|
+ assert container.get('HostConfig.NetworkMode') == name
|
|
|
|
|
+
|
|
|
|
|
+ def test_up_external_networks(self):
|
|
|
|
|
+ filename = 'external-networks.yml'
|
|
|
|
|
+
|
|
|
|
|
+ self.base_dir = 'tests/fixtures/networks'
|
|
|
|
|
+ self._project = get_project(self.base_dir, [filename])
|
|
|
|
|
+
|
|
|
|
|
+ result = self.dispatch(['-f', filename, 'up', '-d'], returncode=1)
|
|
|
|
|
+ assert 'declared as external, but could not be found' in result.stderr
|
|
|
|
|
+
|
|
|
|
|
+ networks = [
|
|
|
|
|
+ n['Name'] for n in self.client.networks()
|
|
|
|
|
+ if n['Name'].startswith('{}_'.format(self.project.name))
|
|
|
|
|
+ ]
|
|
|
|
|
+ assert not networks
|
|
|
|
|
+
|
|
|
|
|
+ network_names = ['{}_{}'.format(self.project.name, n) for n in ['foo', 'bar']]
|
|
|
|
|
+ for name in network_names:
|
|
|
|
|
+ self.client.create_network(name)
|
|
|
|
|
+
|
|
|
|
|
+ self.dispatch(['-f', filename, 'up', '-d'])
|
|
|
|
|
+ container = self.project.containers()[0]
|
|
|
|
|
+ assert sorted(list(container.get('NetworkSettings.Networks'))) == sorted(network_names)
|
|
|
|
|
+
|
|
|
|
|
+ def test_up_no_services(self):
|
|
|
|
|
+ self.base_dir = 'tests/fixtures/no-services'
|
|
|
|
|
+ self.dispatch(['up', '-d'], None)
|
|
|
|
|
+
|
|
|
|
|
+ network_names = [
|
|
|
|
|
+ n['Name'] for n in self.client.networks()
|
|
|
|
|
+ if n['Name'].startswith('{}_'.format(self.project.name))
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ assert sorted(network_names) == [
|
|
|
|
|
+ '{}_{}'.format(self.project.name, name)
|
|
|
|
|
+ for name in ['bar', 'foo']
|
|
|
|
|
+ ]
|
|
|
|
|
|
|
|
def test_up_with_links_is_invalid(self):
|
|
def test_up_with_links_is_invalid(self):
|
|
|
self.base_dir = 'tests/fixtures/v2-simple'
|
|
self.base_dir = 'tests/fixtures/v2-simple'
|
|
@@ -402,13 +507,48 @@ class CLITestCase(DockerClientTestCase):
|
|
|
def test_up_with_links_v1(self):
|
|
def test_up_with_links_v1(self):
|
|
|
self.base_dir = 'tests/fixtures/links-composefile'
|
|
self.base_dir = 'tests/fixtures/links-composefile'
|
|
|
self.dispatch(['up', '-d', 'web'], None)
|
|
self.dispatch(['up', '-d', 'web'], None)
|
|
|
|
|
+
|
|
|
|
|
+ # No network was created
|
|
|
|
|
+ networks = self.client.networks(names=[self.project.default_network.full_name])
|
|
|
|
|
+ assert networks == []
|
|
|
|
|
+
|
|
|
web = self.project.get_service('web')
|
|
web = self.project.get_service('web')
|
|
|
db = self.project.get_service('db')
|
|
db = self.project.get_service('db')
|
|
|
console = self.project.get_service('console')
|
|
console = self.project.get_service('console')
|
|
|
|
|
+
|
|
|
|
|
+ # console was not started
|
|
|
self.assertEqual(len(web.containers()), 1)
|
|
self.assertEqual(len(web.containers()), 1)
|
|
|
self.assertEqual(len(db.containers()), 1)
|
|
self.assertEqual(len(db.containers()), 1)
|
|
|
self.assertEqual(len(console.containers()), 0)
|
|
self.assertEqual(len(console.containers()), 0)
|
|
|
|
|
|
|
|
|
|
+ # web has links
|
|
|
|
|
+ web_container = web.containers()[0]
|
|
|
|
|
+ self.assertTrue(web_container.get('HostConfig.Links'))
|
|
|
|
|
+
|
|
|
|
|
+ def test_up_with_net_is_invalid(self):
|
|
|
|
|
+ self.base_dir = 'tests/fixtures/net-container'
|
|
|
|
|
+
|
|
|
|
|
+ result = self.dispatch(
|
|
|
|
|
+ ['-f', 'v2-invalid.yml', 'up', '-d'],
|
|
|
|
|
+ returncode=1)
|
|
|
|
|
+
|
|
|
|
|
+ # TODO: fix validation error messages for v2 files
|
|
|
|
|
+ # assert "Unsupported config option for service 'web': 'net'" in exc.exconly()
|
|
|
|
|
+ assert "Unsupported config option" in result.stderr
|
|
|
|
|
+
|
|
|
|
|
+ def test_up_with_net_v1(self):
|
|
|
|
|
+ self.base_dir = 'tests/fixtures/net-container'
|
|
|
|
|
+ self.dispatch(['up', '-d'], None)
|
|
|
|
|
+
|
|
|
|
|
+ bar = self.project.get_service('bar')
|
|
|
|
|
+ bar_container = bar.containers()[0]
|
|
|
|
|
+
|
|
|
|
|
+ foo = self.project.get_service('foo')
|
|
|
|
|
+ foo_container = foo.containers()[0]
|
|
|
|
|
+
|
|
|
|
|
+ assert foo_container.get('HostConfig.NetworkMode') == \
|
|
|
|
|
+ 'container:{}'.format(bar_container.id)
|
|
|
|
|
+
|
|
|
def test_up_with_no_deps(self):
|
|
def test_up_with_no_deps(self):
|
|
|
self.base_dir = 'tests/fixtures/links-composefile'
|
|
self.base_dir = 'tests/fixtures/links-composefile'
|
|
|
self.dispatch(['up', '-d', '--no-deps', 'web'], None)
|
|
self.dispatch(['up', '-d', '--no-deps', 'web'], None)
|
|
@@ -698,9 +838,7 @@ class CLITestCase(DockerClientTestCase):
|
|
|
self.dispatch(['run', 'simple', 'true'], None)
|
|
self.dispatch(['run', 'simple', 'true'], None)
|
|
|
service = self.project.get_service('simple')
|
|
service = self.project.get_service('simple')
|
|
|
container, = service.containers(stopped=True, one_off=True)
|
|
container, = service.containers(stopped=True, one_off=True)
|
|
|
- networks = self.client.networks(names=[self.project.default_network_name])
|
|
|
|
|
- for n in networks:
|
|
|
|
|
- self.addCleanup(self.client.remove_network, n['Id'])
|
|
|
|
|
|
|
+ networks = self.client.networks(names=[self.project.default_network.full_name])
|
|
|
self.assertEqual(len(networks), 1)
|
|
self.assertEqual(len(networks), 1)
|
|
|
self.assertEqual(container.human_readable_command, u'true')
|
|
self.assertEqual(container.human_readable_command, u'true')
|
|
|
|
|
|
|
@@ -858,7 +996,7 @@ class CLITestCase(DockerClientTestCase):
|
|
|
def test_restart(self):
|
|
def test_restart(self):
|
|
|
service = self.project.get_service('simple')
|
|
service = self.project.get_service('simple')
|
|
|
container = service.create_container()
|
|
container = service.create_container()
|
|
|
- container.start()
|
|
|
|
|
|
|
+ service.start_container(container)
|
|
|
started_at = container.dictionary['State']['StartedAt']
|
|
started_at = container.dictionary['State']['StartedAt']
|
|
|
self.dispatch(['restart', '-t', '1'], None)
|
|
self.dispatch(['restart', '-t', '1'], None)
|
|
|
container.inspect()
|
|
container.inspect()
|