summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoffrey F <joffrey@docker.com>2015-04-27 13:41:48 -0700
committerJoffrey F <joffrey@docker.com>2015-04-27 13:57:15 -0700
commite2ad91bdf712d5630e47c5077ac7b02afe5ded44 (patch)
tree74c08800959478312c9eb349c93a9e91d7e701b7
parent0fd70b47e305b6f1e735cf07b78381001048cf87 (diff)
downloaddocker-py-e2ad91bdf712d5630e47c5077ac7b02afe5ded44.tar.gz
Exec API tests
-rw-r--r--docker/client.py2
-rw-r--r--tests/fake_api.py42
-rw-r--r--tests/integration_test.py37
-rw-r--r--tests/test.py95
4 files changed, 148 insertions, 28 deletions
diff --git a/docker/client.py b/docker/client.py
index 7e9ff3a..e978dff 100644
--- a/docker/client.py
+++ b/docker/client.py
@@ -569,7 +569,7 @@ class Client(requests.Session):
'w': width
}
res = self._post_json(
- self._url('exec/{0}/resize'.format(exec_id)), data
+ self._url('/exec/{0}/resize'.format(exec_id)), data
)
res.raise_for_status()
diff --git a/tests/fake_api.py b/tests/fake_api.py
index 33181ce..2ee146e 100644
--- a/tests/fake_api.py
+++ b/tests/fake_api.py
@@ -18,6 +18,7 @@ CURRENT_VERSION = 'v1.18'
FAKE_CONTAINER_ID = '3cc2351ab11b'
FAKE_IMAGE_ID = 'e9aa60c60128'
+FAKE_EXEC_ID = 'd5d177f121dc'
FAKE_IMAGE_NAME = 'test_image'
FAKE_TARBALL_PATH = '/path/to/tarball'
FAKE_REPO_NAME = 'repo'
@@ -247,13 +248,13 @@ def get_fake_export():
return status_code, response
-def post_fake_execute():
+def post_fake_exec_create():
status_code = 200
- response = {'Id': FAKE_CONTAINER_ID}
+ response = {'Id': FAKE_EXEC_ID}
return status_code, response
-def post_fake_execute_start():
+def post_fake_exec_start():
status_code = 200
response = (b'\x01\x00\x00\x00\x00\x00\x00\x11bin\nboot\ndev\netc\n'
b'\x01\x00\x00\x00\x00\x00\x00\x12lib\nmnt\nproc\nroot\n'
@@ -261,6 +262,30 @@ def post_fake_execute_start():
return status_code, response
+def post_fake_exec_resize():
+ status_code = 201
+ return status_code, ''
+
+
+def get_fake_exec_inspect():
+ return 200, {
+ 'OpenStderr': True,
+ 'OpenStdout': True,
+ 'Container': get_fake_inspect_container()[1],
+ 'Running': False,
+ 'ProcessConfig': {
+ 'arguments': ['hello world'],
+ 'tty': False,
+ 'entrypoint': 'echo',
+ 'privileged': False,
+ 'user': ''
+ },
+ 'ExitCode': 0,
+ 'ID': FAKE_EXEC_ID,
+ 'OpenStdin': False
+ }
+
+
def post_fake_stop_container():
status_code = 200
response = {'Id': FAKE_CONTAINER_ID}
@@ -393,9 +418,14 @@ fake_responses = {
'{1}/{0}/containers/3cc2351ab11b/export'.format(CURRENT_VERSION, prefix):
get_fake_export,
'{1}/{0}/containers/3cc2351ab11b/exec'.format(CURRENT_VERSION, prefix):
- post_fake_execute,
- '{1}/{0}/exec/3cc2351ab11b/start'.format(CURRENT_VERSION, prefix):
- post_fake_execute_start,
+ post_fake_exec_create,
+ '{1}/{0}/exec/d5d177f121dc/start'.format(CURRENT_VERSION, prefix):
+ post_fake_exec_start,
+ '{1}/{0}/exec/d5d177f121dc/json'.format(CURRENT_VERSION, prefix):
+ get_fake_exec_inspect,
+ '{1}/{0}/exec/d5d177f121dc/resize'.format(CURRENT_VERSION, prefix):
+ post_fake_exec_resize,
+
'{1}/{0}/containers/3cc2351ab11b/stats'.format(CURRENT_VERSION, prefix):
get_fake_stats,
'{1}/{0}/containers/3cc2351ab11b/stop'.format(CURRENT_VERSION, prefix):
diff --git a/tests/integration_test.py b/tests/integration_test.py
index 21679d7..0db3052 100644
--- a/tests/integration_test.py
+++ b/tests/integration_test.py
@@ -1071,9 +1071,12 @@ class TestExecuteCommand(BaseTestCase):
self.client.start(id)
self.tmp_containers.append(id)
- res = self.client.execute(id, ['echo', 'hello'])
+ res = self.client.exec_create(id, ['echo', 'hello'])
+ self.assertIn('Id', res)
+
+ exec_log = self.client.exec_start(res)
expected = b'hello\n' if six.PY3 else 'hello\n'
- self.assertEqual(res, expected)
+ self.assertEqual(exec_log, expected)
@unittest.skipIf(not EXEC_DRIVER_IS_NATIVE, 'Exec driver not native')
@@ -1085,9 +1088,12 @@ class TestExecuteCommandString(BaseTestCase):
self.client.start(id)
self.tmp_containers.append(id)
- res = self.client.execute(id, 'echo hello world', stdout=True)
+ res = self.client.exec_create(id, 'echo hello world')
+ self.assertIn('Id', res)
+
+ exec_log = self.client.exec_start(res)
expected = b'hello world\n' if six.PY3 else 'hello world\n'
- self.assertEqual(res, expected)
+ self.assertEqual(exec_log, expected)
@unittest.skipIf(not EXEC_DRIVER_IS_NATIVE, 'Exec driver not native')
@@ -1099,14 +1105,33 @@ class TestExecuteCommandStreaming(BaseTestCase):
self.client.start(id)
self.tmp_containers.append(id)
- chunks = self.client.execute(id, ['echo', 'hello\nworld'], stream=True)
+ exec_id = self.client.exec_create(id, ['echo', 'hello\nworld'])
+ self.assertIn('Id', exec_id)
+
res = b'' if six.PY3 else ''
- for chunk in chunks:
+ for chunk in self.client.exec_start(exec_id, stream=True):
res += chunk
expected = b'hello\nworld\n' if six.PY3 else 'hello\nworld\n'
self.assertEqual(res, expected)
+@unittest.skipIf(not EXEC_DRIVER_IS_NATIVE, 'Exec driver not native')
+class TestExecInspect(BaseTestCase):
+ def runTest(self):
+ container = self.client.create_container('busybox', 'cat',
+ detach=True, stdin_open=True)
+ id = container['Id']
+ self.client.start(id)
+ self.tmp_containers.append(id)
+
+ exec_id = self.client.exec_create(id, ['mkdir', '/does/not/exist'])
+ self.assertIn('Id', exec_id)
+ self.client.exec_start(exec_id)
+ exec_info = self.client.exec_inspect(exec_id)
+ self.assertIn('ExitCode', exec_info)
+ self.assertNotEqual(exec_info['ExitCode'], 0)
+
+
class TestRunContainerStreaming(BaseTestCase):
def runTest(self):
container = self.client.create_container('busybox', '/bin/sh',
diff --git a/tests/test.py b/tests/test.py
index 76c5638..95a8463 100644
--- a/tests/test.py
+++ b/tests/test.py
@@ -1583,31 +1583,96 @@ class DockerClientTest(Cleanup, base.BaseTestCase):
timeout=(docker.client.DEFAULT_TIMEOUT_SECONDS + timeout)
)
- def test_execute_command(self):
+ def test_exec_create(self):
try:
- self.client.execute(fake_api.FAKE_CONTAINER_ID, ['ls', '-1'])
+ self.client.exec_create(fake_api.FAKE_CONTAINER_ID, ['ls', '-1'])
except Exception as e:
self.fail('Command should not raise exception: {0}'.format(e))
args = fake_request.call_args
- self.assertEqual(args[0][0],
- url_prefix + 'exec/3cc2351ab11b/start')
+ self.assertEqual(
+ args[0][0], url_prefix + 'containers/{0}/exec'.format(
+ fake_api.FAKE_CONTAINER_ID
+ )
+ )
- self.assertEqual(json.loads(args[1]['data']),
- json.loads('''{
- "Tty": false,
- "AttachStderr": true,
- "Container": "3cc2351ab11b",
- "Cmd": ["ls", "-1"],
- "AttachStdin": false,
- "User": "",
- "Detach": false,
- "Privileged": false,
- "AttachStdout": true}'''))
+ self.assertEqual(
+ json.loads(args[1]['data']), {
+ 'Tty': False,
+ 'AttachStdout': True,
+ 'Container': fake_api.FAKE_CONTAINER_ID,
+ 'Detach': False,
+ 'Cmd': ['ls', '-1'],
+ 'Privileged': False,
+ 'AttachStdin': False,
+ 'AttachStderr': True,
+ 'User': ''
+ }
+ )
self.assertEqual(args[1]['headers'],
{'Content-Type': 'application/json'})
+ def test_exec_start(self):
+ try:
+ self.client.exec_start(fake_api.FAKE_EXEC_ID)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(
+ args[0][0], url_prefix + 'exec/{0}/start'.format(
+ fake_api.FAKE_EXEC_ID
+ )
+ )
+
+ self.assertEqual(
+ json.loads(args[1]['data']), {
+ 'Tty': False,
+ 'Detach': False,
+ }
+ )
+
+ self.assertEqual(args[1]['headers'],
+ {'Content-Type': 'application/json'})
+
+ def test_exec_inspect(self):
+ try:
+ self.client.exec_inspect(fake_api.FAKE_EXEC_ID)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(
+ args[0][0], url_prefix + 'exec/{0}/json'.format(
+ fake_api.FAKE_EXEC_ID
+ )
+ )
+
+ def test_exec_resize(self):
+ try:
+ self.client.exec_resize(fake_api.FAKE_EXEC_ID, height=20, width=60)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(
+ args[0][0], url_prefix + 'exec/{0}/resize'.format(
+ fake_api.FAKE_EXEC_ID
+ )
+ )
+
+ self.assertEqual(
+ json.loads(args[1]['data']), {
+ 'h': 20,
+ 'w': 60,
+ }
+ )
+
+ self.assertEqual(
+ args[1]['headers'], {'Content-Type': 'application/json'}
+ )
+
def test_pause_container(self):
try:
self.client.pause(fake_api.FAKE_CONTAINER_ID)