mirror of https://github.com/docker/docker-py.git
Add integration tests for Client.import_image() function
Currently TestImportFromStream fails, because something is going wrong with the HTTP chunked transfer-encoding. This didn't work before, either (for a different reason).
This commit is contained in:
parent
8ce1e248cd
commit
b1d4a5d8d1
|
|
@ -12,24 +12,31 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import time
|
||||
import base64
|
||||
import contextlib
|
||||
import json
|
||||
import io
|
||||
import os
|
||||
import shutil
|
||||
import signal
|
||||
import socket
|
||||
import tarfile
|
||||
import tempfile
|
||||
import threading
|
||||
import time
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
import docker
|
||||
import six
|
||||
|
||||
from six.moves import BaseHTTPServer
|
||||
from six.moves import socketserver
|
||||
|
||||
from test import Cleanup
|
||||
|
||||
# FIXME: missing tests for
|
||||
# export; history; import_image; insert; port; push; tag; get; load
|
||||
# export; history; insert; port; push; tag; get; load
|
||||
|
||||
DEFAULT_BASE_URL = os.environ.get('DOCKER_HOST')
|
||||
|
||||
|
|
@ -1023,6 +1030,157 @@ class TestRemoveImage(BaseTestCase):
|
|||
res = [x for x in images if x['Id'].startswith(img_id)]
|
||||
self.assertEqual(len(res), 0)
|
||||
|
||||
|
||||
##################
|
||||
# IMPORT TESTS #
|
||||
##################
|
||||
|
||||
|
||||
class ImportTestCase(BaseTestCase):
|
||||
'''Base class for `docker import` test cases.'''
|
||||
|
||||
# Use a large file size to increase the chance of triggering any
|
||||
# MemoryError exceptions we might hit.
|
||||
TAR_SIZE = 512 * 1024 * 1024
|
||||
|
||||
def write_dummy_tar_content(self, n_bytes, tar_fd):
|
||||
def extend_file(f, n_bytes):
|
||||
f.seek(n_bytes - 1)
|
||||
f.write(bytearray([65]))
|
||||
f.seek(0)
|
||||
|
||||
tar = tarfile.TarFile(fileobj=tar_fd, mode='w')
|
||||
|
||||
with tempfile.NamedTemporaryFile() as f:
|
||||
extend_file(f, n_bytes)
|
||||
tarinfo = tar.gettarinfo(name=f.name, arcname='testdata')
|
||||
tar.addfile(tarinfo, fileobj=f)
|
||||
|
||||
tar.close()
|
||||
|
||||
@contextlib.contextmanager
|
||||
def dummy_tar_stream(self, n_bytes):
|
||||
'''Yields a stream that is valid tar data of size n_bytes.'''
|
||||
with tempfile.NamedTemporaryFile() as tar_file:
|
||||
self.write_dummy_tar_content(n_bytes, tar_file)
|
||||
tar_file.seek(0)
|
||||
yield tar_file
|
||||
|
||||
@contextlib.contextmanager
|
||||
def dummy_tar_file(self, n_bytes):
|
||||
'''Yields the name of a valid tar file of size n_bytes.'''
|
||||
with tempfile.NamedTemporaryFile() as tar_file:
|
||||
self.write_dummy_tar_content(n_bytes, tar_file)
|
||||
tar_file.seek(0)
|
||||
yield tar_file.name
|
||||
|
||||
|
||||
class TestImportFromBytes(ImportTestCase):
|
||||
'''Tests importing an image from in-memory byte data.'''
|
||||
|
||||
def runTest(self):
|
||||
with self.dummy_tar_stream(n_bytes=500) as f:
|
||||
content = f.read()
|
||||
|
||||
# The generic import_image() function cannot import in-memory bytes
|
||||
# data that happens to be represented as a string type, because
|
||||
# import_image() will try to use it as a filename and usually then
|
||||
# trigger an exception. So we test the import_image_from_data()
|
||||
# function instead.
|
||||
statuses = self.client.import_image_from_data(
|
||||
content, repository='test/import-from-bytes')
|
||||
|
||||
result_text = statuses.splitlines()[-1]
|
||||
result = json.loads(result_text)
|
||||
|
||||
self.assertNotIn('error', result)
|
||||
|
||||
img_id = result['status']
|
||||
self.tmp_imgs.append(img_id)
|
||||
|
||||
|
||||
class TestImportFromFile(ImportTestCase):
|
||||
'''Tests importing an image from a tar file on disk.'''
|
||||
|
||||
def runTest(self):
|
||||
with self.dummy_tar_file(n_bytes=self.TAR_SIZE) as tar_filename:
|
||||
# statuses = self.client.import_image(
|
||||
# src=tar_filename, repository='test/import-from-file')
|
||||
statuses = self.client.import_image_from_file(
|
||||
tar_filename, repository='test/import-from-file')
|
||||
|
||||
result_text = statuses.splitlines()[-1]
|
||||
result = json.loads(result_text)
|
||||
|
||||
self.assertNotIn('error', result)
|
||||
|
||||
self.assertIn('status', result)
|
||||
img_id = result['status']
|
||||
self.tmp_imgs.append(img_id)
|
||||
|
||||
|
||||
class TestImportFromStream(ImportTestCase):
|
||||
'''Tests importing an image from a stream containing tar data.'''
|
||||
|
||||
def runTest(self):
|
||||
with self.dummy_tar_stream(n_bytes=self.TAR_SIZE) as tar_stream:
|
||||
statuses = self.client.import_image(
|
||||
src=tar_stream, repository='test/import-from-stream')
|
||||
# statuses = self.client.import_image_from_stream(
|
||||
# tar_stream, repository='test/import-from-stream')
|
||||
result_text = statuses.splitlines()[-1]
|
||||
result = json.loads(result_text)
|
||||
|
||||
self.assertNotIn('error', result)
|
||||
|
||||
self.assertIn('status', result)
|
||||
img_id = result['status']
|
||||
self.tmp_imgs.append(img_id)
|
||||
|
||||
|
||||
class TestImportFromURL(ImportTestCase):
|
||||
'''Tests downloading an image over HTTP.'''
|
||||
|
||||
@contextlib.contextmanager
|
||||
def temporary_http_file_server(self, stream):
|
||||
'''Serve data from an IO stream over HTTP.'''
|
||||
|
||||
class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
self.send_response(200)
|
||||
self.send_header('Content-Type', 'application/x-tar')
|
||||
self.end_headers()
|
||||
shutil.copyfileobj(stream, self.wfile)
|
||||
|
||||
server = socketserver.TCPServer(('', 0), Handler)
|
||||
thread = threading.Thread(target=server.serve_forever)
|
||||
thread.setDaemon(True)
|
||||
thread.start()
|
||||
|
||||
yield 'http://%s:%s' % (socket.gethostname(), server.server_address[1])
|
||||
|
||||
server.shutdown()
|
||||
|
||||
def runTest(self):
|
||||
# The crappy test HTTP server doesn't handle large files well, so use
|
||||
# a small file.
|
||||
TAR_SIZE = 10240
|
||||
|
||||
with self.dummy_tar_stream(n_bytes=TAR_SIZE) as tar_data:
|
||||
with self.temporary_http_file_server(tar_data) as url:
|
||||
statuses = self.client.import_image(
|
||||
src=url, repository='test/import-from-url')
|
||||
|
||||
result_text = statuses.splitlines()[-1]
|
||||
result = json.loads(result_text)
|
||||
|
||||
self.assertNotIn('error', result)
|
||||
|
||||
self.assertIn('status', result)
|
||||
img_id = result['status']
|
||||
self.tmp_imgs.append(img_id)
|
||||
|
||||
|
||||
#################
|
||||
# BUILDER TESTS #
|
||||
#################
|
||||
|
|
|
|||
Loading…
Reference in New Issue