added versioning for docker and split fixtures
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/5101531a Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/5101531a Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/5101531a Branch: refs/heads/trunk Commit: 5101531a5a22d80399cc3c700011516b25b9330a Parents: 6dfe940 Author: Anthony Shaw <anthonys...@apache.org> Authored: Fri Jun 24 11:53:11 2016 +1000 Committer: Anthony Shaw <anthonys...@apache.org> Committed: Fri Jun 24 11:53:11 2016 +1000 ---------------------------------------------------------------------- libcloud/container/drivers/docker.py | 58 +++-- .../fixtures/docker/mac_124/version.json | 11 + libcloud/test/container/test_docker.py | 253 ++++++++++--------- 3 files changed, 180 insertions(+), 142 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/5101531a/libcloud/container/drivers/docker.py ---------------------------------------------------------------------- diff --git a/libcloud/container/drivers/docker.py b/libcloud/container/drivers/docker.py index ae360cf..76c3474 100644 --- a/libcloud/container/drivers/docker.py +++ b/libcloud/container/drivers/docker.py @@ -130,6 +130,7 @@ class DockerContainerDriver(ContainerDriver): website = 'http://docker.io' connectionCls = DockerConnection supports_clusters = False + version = '1.24' def __init__(self, key=None, secret=None, secure=False, host='localhost', port=4243, key_file=None, cert_file=None): @@ -204,8 +205,9 @@ class DockerContainerDriver(ContainerDriver): } data = json.dumps(payload) - result = self.connection.request('/images/create?fromImage=%s' % - (path), data=data, method='POST') + result = self.connection.request('v%s/images/create?fromImage=%s' % + (self.version, path), data=data, + method='POST') if "errorDetail" in result.body: raise DockerException(None, result.body) try: @@ -233,7 +235,7 @@ class DockerContainerDriver(ContainerDriver): :rtype: ``list`` of :class:`libcloud.container.base.ContainerImage` """ - result = self.connection.request('/images/json').object + result = self.connection.request('v%s/images/json' % (self.version)).object images = [] for image in result: try: @@ -273,7 +275,7 @@ class DockerContainerDriver(ContainerDriver): ex = '' try: result = self.connection.request( - "/containers/json%s" % (ex)).object + "v%s/containers/json%s" % (self.version, ex)).object except Exception as exc: errno = getattr(exc, 'errno', None) if errno == 111: @@ -349,7 +351,8 @@ class DockerContainerDriver(ContainerDriver): data = json.dumps(payload) try: - result = self.connection.request('/containers/create', data=data, + result = self.connection.request('v%s/containers/create' % self.version, + data=data, params=params, method='POST') except Exception as e: message = e.message or str(e) @@ -369,7 +372,8 @@ class DockerContainerDriver(ContainerDriver): data = json.dumps(payload) if start: result = self.connection.request( - '/containers/%s/start' % id_, data=data, + 'v%s/containers/%s/start' % + (self.version, id_), data=data, method='POST') return self.get_container(id_) @@ -383,8 +387,8 @@ class DockerContainerDriver(ContainerDriver): :rtype: :class:`libcloud.container.base.Container` """ - result = self.connection.request("/containers/%s/json" % - id).object + result = self.connection.request("v%s/containers/%s/json" % + (self.version, id)).object return self._to_container(result) @@ -404,8 +408,8 @@ class DockerContainerDriver(ContainerDriver): } data = json.dumps(payload) result = self.connection.request( - '/containers/%s/start' % - (container.id), + 'v%s/containers/%s/start' % + (self.version, container.id), method='POST', data=data) if result.status in VALID_RESPONSE_CODES: return self.get_container(container.id) @@ -423,8 +427,8 @@ class DockerContainerDriver(ContainerDriver): :return: The container refreshed with current data :rtype: :class:`libcloud.container.base.Container` """ - result = self.connection.request('/containers/%s/stop' % - (container.id), + result = self.connection.request('v%s/containers/%s/stop' % + (self.version, container.id), method='POST') if result.status in VALID_RESPONSE_CODES: return self.get_container(container.id) @@ -444,8 +448,8 @@ class DockerContainerDriver(ContainerDriver): """ data = json.dumps({'t': 10}) # number of seconds to wait before killing the container - result = self.connection.request('/containers/%s/restart' % - (container.id), + result = self.connection.request('v%s/containers/%s/restart' % + (self.version, container.id), data=data, method='POST') if result.status in VALID_RESPONSE_CODES: return self.get_container(container.id) @@ -463,7 +467,8 @@ class DockerContainerDriver(ContainerDriver): :return: True if the destroy was successful, False otherwise. :rtype: ``bool`` """ - result = self.connection.request('/containers/%s' % (container.id), + result = self.connection.request('v%s/containers/%s' % (self.version, + container.id), method='DELETE') return result.status in VALID_RESPONSE_CODES @@ -476,8 +481,8 @@ class DockerContainerDriver(ContainerDriver): :rtype: ``str`` """ - result = self.connection.request("/containers/%s/top" % - container.id).object + result = self.connection.request("v%s/containers/%s/top" % + (self.version, container.id)).object return result @@ -493,8 +498,8 @@ class DockerContainerDriver(ContainerDriver): :rtype: :class:`libcloud.container.base.Container` """ - result = self.connection.request('/containers/%s/rename?name=%s' - % (container.id, name), + result = self.connection.request('v%s/containers/%s/rename?name=%s' + % (self.version, container.id, name), method='POST') if result.status in VALID_RESPONSE_CODES: return self.get_container(container.id) @@ -520,13 +525,13 @@ class DockerContainerDriver(ContainerDriver): if float(self._get_api_version()) > 1.10: result = self.connection.request( - "/containers/%s/logs?follow=%s&stdout=1&stderr=1" % - (container.id, str(stream))).object + "v%s/containers/%s/logs?follow=%s&stdout=1&stderr=1" % + (self.version, container.id, str(stream))).object logs = result else: result = self.connection.request( - "/containers/%s/attach?logs=1&stream=%s&stdout=1&stderr=1" % - (container.id, str(stream)), method='POST', data=data) + "v%s/containers/%s/attach?logs=1&stream=%s&stdout=1&stderr=1" % + (self.version, container.id, str(stream)), method='POST', data=data) logs = result.body return logs @@ -548,8 +553,8 @@ class DockerContainerDriver(ContainerDriver): """ term = term.replace(' ', '+') - result = self.connection.request('/images/search?term=%s' % - term).object + result = self.connection.request('v%s/images/search?term=%s' % + (self.version, term)).object images = [] for image in result: name = image.get('name') @@ -579,7 +584,8 @@ class DockerContainerDriver(ContainerDriver): :rtype: ``bool`` """ - result = self.connection.request('/images/%s' % (image.name), + result = self.connection.request('v%s/images/%s' % (self.version, + image.name), method='DELETE') return result.status in VALID_RESPONSE_CODES http://git-wip-us.apache.org/repos/asf/libcloud/blob/5101531a/libcloud/test/container/fixtures/docker/mac_124/version.json ---------------------------------------------------------------------- diff --git a/libcloud/test/container/fixtures/docker/mac_124/version.json b/libcloud/test/container/fixtures/docker/mac_124/version.json new file mode 100644 index 0000000..e07d466 --- /dev/null +++ b/libcloud/test/container/fixtures/docker/mac_124/version.json @@ -0,0 +1,11 @@ +{ + "Version": "1.12.0-rc2", + "ApiVersion": "1.24", + "GitCommit": "a7119de", + "GoVersion": "go1.6.2", + "Os": "linux", + "Arch": "amd64", + "KernelVersion": "4.4.13-moby", + "Experimental": true, + "BuildTime": "2016-06-17T22:09:20.440355664+00:00" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/5101531a/libcloud/test/container/test_docker.py ---------------------------------------------------------------------- diff --git a/libcloud/test/container/test_docker.py b/libcloud/test/container/test_docker.py index a1978f7..7e18557 100644 --- a/libcloud/test/container/test_docker.py +++ b/libcloud/test/container/test_docker.py @@ -14,6 +14,8 @@ # limitations under the License. import sys +import os +from functools import wraps from libcloud.test import unittest @@ -30,183 +32,202 @@ from libcloud.test import MockHttp class DockerContainerDriverTestCase(unittest.TestCase): def setUp(self): - DockerContainerDriver.connectionCls.conn_classes = ( - DockerMockHttp, DockerMockHttp) - DockerMockHttp.type = None - DockerMockHttp.use_param = 'a' - self.driver = DockerContainerDriver(*CONTAINER_PARAMS_DOCKER) + # Create a test driver for each version + versions = ('linux_121', 'mac_124') + self.drivers = [] + for version in versions: + DockerContainerDriver.connectionCls.conn_classes = ( + DockerMockHttp, DockerMockHttp) + DockerMockHttp.type = None + DockerMockHttp.use_param = 'a' + driver = DockerContainerDriver(*CONTAINER_PARAMS_DOCKER) + driver.version = version + self.drivers.append(driver) def test_list_images(self): - images = self.driver.list_images() - self.assertEqual(len(images), 4) - self.assertIsInstance(images[0], ContainerImage) - self.assertEqual(images[0].id, - 'cf55d61f5307b7a18a45980971d6cfd40b737dd661879c4a6b3f2aecc3bc37b0') - self.assertEqual(images[0].name, 'mongo:latest') + for driver in self.drivers: + images = driver.list_images() + self.assertEqual(len(images), 4) + self.assertIsInstance(images[0], ContainerImage) + self.assertEqual(images[0].id, + 'cf55d61f5307b7a18a45980971d6cfd40b737dd661879c4a6b3f2aecc3bc37b0') + self.assertEqual(images[0].name, 'mongo:latest') def test_install_image(self): - image = self.driver.install_image('ubuntu:12.04') - self.assertTrue(image is not None) - self.assertEqual(image.id, 'cf55d61f5307b7a18a45980971d6cfd40b737dd661879c4a6b3f2aecc3bc37b0') + for driver in self.drivers: + image = driver.install_image('ubuntu:12.04') + self.assertTrue(image is not None) + self.assertEqual(image.id, 'cf55d61f5307b7a18a45980971d6cfd40b737dd661879c4a6b3f2aecc3bc37b0') def test_list_containers(self): - containers = self.driver.list_containers(all=True) - self.assertEqual(len(containers), 6) - self.assertEqual(containers[0].id, - '160936dc54fe8c332095676d9379003534b8cddd7565fa63018996e06dae1b6b') - self.assertEqual(containers[0].name, 'hubot') - self.assertEqual(containers[0].image.name, 'stackstorm/hubot') + for driver in self.drivers: + containers = driver.list_containers(all=True) + self.assertEqual(len(containers), 6) + self.assertEqual(containers[0].id, + '160936dc54fe8c332095676d9379003534b8cddd7565fa63018996e06dae1b6b') + self.assertEqual(containers[0].name, 'hubot') + self.assertEqual(containers[0].image.name, 'stackstorm/hubot') def test_deploy_container(self): - image = self.driver.list_images()[0] - container = self.driver.deploy_container(image=image, name='test') - self.assertEqual(container.id, 'a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - self.assertEqual(container.name, 'gigantic_goldberg') + for driver in self.drivers: + image = driver.list_images()[0] + container = driver.deploy_container(image=image, name='test') + self.assertEqual(container.id, 'a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + self.assertEqual(container.name, 'gigantic_goldberg') def test_get_container(self): - container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - self.assertEqual(container.id, 'a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - self.assertEqual(container.name, 'gigantic_goldberg') + for driver in self.drivers: + container = driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + self.assertEqual(container.id, 'a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + self.assertEqual(container.name, 'gigantic_goldberg') def test_start_container(self): - container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - container.start() + for driver in self.drivers: + container = driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + container.start() def test_stop_container(self): - container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - container.stop() + for driver in self.drivers: + container = driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + container.stop() def test_restart_container(self): - container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - container.restart() + for driver in self.drivers: + container = driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + container.restart() def test_delete_container(self): - container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - container.destroy() + for driver in self.drivers: + container = driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + container.destroy() def test_ex_rename_container(self): - container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - self.driver.ex_rename_container(container, 'bob') + for driver in self.drivers: + container = driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + driver.ex_rename_container(container, 'bob') def test_ex_get_logs(self): - container = self.driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') - logs = self.driver.ex_get_logs(container) - self.assertTrue(logs is not None) + for driver in self.drivers: + container = driver.get_container('a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303') + logs = driver.ex_get_logs(container) + self.assertTrue(logs is not None) def test_ex_search_images(self): - images = self.driver.ex_search_images('mysql') - self.assertEqual(len(images), 25) - self.assertEqual(images[0].name, 'mysql') + for driver in self.drivers: + images = driver.ex_search_images('mysql') + self.assertEqual(len(images), 25) + self.assertEqual(images[0].name, 'mysql') class DockerMockHttp(MockHttp): fixtures = ContainerFileFixtures('docker') + version = None def _version( self, method, url, body, headers): if method == 'GET': - body = self.fixtures.load('version.json') + body = self.fixtures.load('linux_121/version.json') else: raise AssertionError('Unsupported method') return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - def _images_search( + def vlinux_121_images_search( self, method, url, body, headers): - if method == 'GET': - body = self.fixtures.load('search.json') - else: - raise AssertionError('Unsupported method') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + return (httplib.OK, self.fixtures.load('linux_121/search.json'), {}, httplib.responses[httplib.OK]) - def _images_json( + def vmac_124_images_search( self, method, url, body, headers): - if method == 'GET': - body = self.fixtures.load('images.json') - else: - raise AssertionError('Unsupported method') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + return (httplib.OK, self.fixtures.load('mac_124/search.json'), {}, httplib.responses[httplib.OK]) - def _images_create( + def vlinux_121_images_json( self, method, url, body, headers): - if method == 'POST': - body = self.fixtures.load('create_image.json') - else: - raise AssertionError('Unsupported method') - return (httplib.OK, body, {'Content-Type': 'application/json'}, + return (httplib.OK, self.fixtures.load('linux_121/images.json'), {}, httplib.responses[httplib.OK]) + + def vmac_124_images_json( + self, method, url, body, headers): + return (httplib.OK, self.fixtures.load('linux_121/images.json'), {}, httplib.responses[httplib.OK]) + + def vlinux_121_images_create( + self, method, url, body, headers): + return (httplib.OK, self.fixtures.load('linux_121/create_image.json'), {'Content-Type': 'application/json'}, httplib.responses[httplib.OK]) - def _containers_json( + def vmac_124_images_create( self, method, url, body, headers): - if method == 'GET': - body = self.fixtures.load('containers.json') - else: - raise AssertionError('Unsupported method') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + return (httplib.OK, self.fixtures.load('mac_124/create_image.json'), {'Content-Type': 'application/json'}, + httplib.responses[httplib.OK]) - def _containers_create( + def vlinux_121_containers_json( self, method, url, body, headers): - if method == 'POST': - body = self.fixtures.load('create_container.json') - else: - raise AssertionError('Unsupported method') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + return (httplib.OK, self.fixtures.load('linux_121/containers.json'), {}, httplib.responses[httplib.OK]) - def _containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303( + def vmac_124_containers_json( self, method, url, body, headers): - if method == 'DELETE': - body = '' - else: - raise AssertionError('Unsupported method') - return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.OK]) + return (httplib.OK, self.fixtures.load('mac_124/containers.json'), {}, httplib.responses[httplib.OK]) - def _containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_start( + def vlinux_121_containers_create( self, method, url, body, headers): - if method == 'POST': - body = '' - else: - raise AssertionError('Unsupported method') - return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.OK]) + return (httplib.OK, self.fixtures.load('linux_121/create_container.json'), {}, httplib.responses[httplib.OK]) - def _containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_restart( + def vmac_124_containers_create( self, method, url, body, headers): - if method == 'POST': - body = '' - else: - raise AssertionError('Unsupported method') - return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.OK]) + return (httplib.OK, self.fixtures.load('mac_124/create_container.json'), {}, httplib.responses[httplib.OK]) - def _containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_rename( + def vlinux_121_containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303( self, method, url, body, headers): - if method == 'POST': - body = '' - else: - raise AssertionError('Unsupported method') - return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.OK]) + return (httplib.NO_CONTENT, '', {}, httplib.responses[httplib.OK]) - def _containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_stop( + def vmac_124_containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303( self, method, url, body, headers): - if method == 'POST': - body = '' - else: - raise AssertionError('Unsupported method') - return (httplib.NO_CONTENT, body, {}, httplib.responses[httplib.OK]) + return (httplib.NO_CONTENT, '', {}, httplib.responses[httplib.OK]) - def _containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_json( + def vlinux_121_containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_start( self, method, url, body, headers): - if method == 'GET': - body = self.fixtures.load('container_a68.json') - else: - raise AssertionError('Unsupported method') - return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + return (httplib.NO_CONTENT, '', {}, httplib.responses[httplib.OK]) - def _containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_logs( + def vmac_124_containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_start( self, method, url, body, headers): - if method == 'GET': - body = self.fixtures.load('logs.txt') - else: - raise AssertionError('Unsupported method') - return (httplib.OK, body, {'content-type': 'text/plain'}, httplib.responses[httplib.OK]) + return (httplib.NO_CONTENT, '', {}, httplib.responses[httplib.OK]) + + def vlinux_121_containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_restart( + self, method, url, body, headers): + return (httplib.NO_CONTENT, '', {}, httplib.responses[httplib.OK]) + def vmac_124_containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_restart( + self, method, url, body, headers): + return (httplib.NO_CONTENT, '', {}, httplib.responses[httplib.OK]) + + def vlinux_121_containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_rename( + self, method, url, body, headers): + return (httplib.NO_CONTENT, '', {}, httplib.responses[httplib.OK]) + + def vmac_124_containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_rename( + self, method, url, body, headers): + return (httplib.NO_CONTENT, '', {}, httplib.responses[httplib.OK]) + + def vlinux_121_containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_stop( + self, method, url, body, headers): + return (httplib.NO_CONTENT, '', {}, httplib.responses[httplib.OK]) + + def vmac_124_containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_stop( + self, method, url, body, headers): + return (httplib.NO_CONTENT, '', {}, httplib.responses[httplib.OK]) + + def vlinux_121_containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_json( + self, method, url, body, headers): + return (httplib.OK, self.fixtures.load('linux_121/container_a68.json'), {}, httplib.responses[httplib.OK]) + + def vmac_124_containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_json( + self, method, url, body, headers): + return (httplib.OK, self.fixtures.load('linux_121/container_a68.json'), {}, httplib.responses[httplib.OK]) + + def vlinux_121_containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_logs( + self, method, url, body, headers): + return (httplib.OK, self.fixtures.load('linux_121/logs.txt'), {'content-type': 'text/plain'}, httplib.responses[httplib.OK]) + + def vmac_124_containers_a68c1872c74630522c7aa74b85558b06824c5e672cee334296c50fb209825303_logs( + self, method, url, body, headers): + return (httplib.OK, self.fixtures.load('linux_121/logs.txt'), {'content-type': 'text/plain'}, httplib.responses[httplib.OK]) if __name__ == '__main__': sys.exit(unittest.main())