Handle invalid tar layers and add tests
This commit is contained in:
parent
cc9d5798b3
commit
611bc895e1
2 changed files with 55 additions and 0 deletions
|
@ -3,6 +3,7 @@ import tarfile
|
||||||
|
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
from util.streamlayerformat import StreamLayerMerger, AUFS_WHITEOUT
|
from util.streamlayerformat import StreamLayerMerger, AUFS_WHITEOUT
|
||||||
|
from util.tarlayerformat import TarLayerReadException
|
||||||
|
|
||||||
class TestStreamLayerMerger(unittest.TestCase):
|
class TestStreamLayerMerger(unittest.TestCase):
|
||||||
def create_layer(self, **kwargs):
|
def create_layer(self, **kwargs):
|
||||||
|
@ -30,6 +31,9 @@ class TestStreamLayerMerger(unittest.TestCase):
|
||||||
|
|
||||||
return output.getvalue()
|
return output.getvalue()
|
||||||
|
|
||||||
|
def create_empty_layer(self):
|
||||||
|
return ''
|
||||||
|
|
||||||
def squash_layers(self, layers):
|
def squash_layers(self, layers):
|
||||||
def get_layers():
|
def get_layers():
|
||||||
return [StringIO(layer) for layer in layers]
|
return [StringIO(layer) for layer in layers]
|
||||||
|
@ -337,6 +341,7 @@ class TestStreamLayerMerger(unittest.TestCase):
|
||||||
self.assertHasFile(squashed, 'foobar/baz/some_file', 'foo')
|
self.assertHasFile(squashed, 'foobar/baz/some_file', 'foo')
|
||||||
self.assertDoesNotHaveFile(squashed, 'foo/another_file')
|
self.assertDoesNotHaveFile(squashed, 'foo/another_file')
|
||||||
|
|
||||||
|
|
||||||
def test_delete_root_directory(self):
|
def test_delete_root_directory(self):
|
||||||
third_layer = self.create_layer(
|
third_layer = self.create_layer(
|
||||||
foo = 'build/first_file',
|
foo = 'build/first_file',
|
||||||
|
@ -350,5 +355,45 @@ class TestStreamLayerMerger(unittest.TestCase):
|
||||||
self.assertDoesNotHaveFile(squashed, 'build/first_file')
|
self.assertDoesNotHaveFile(squashed, 'build/first_file')
|
||||||
self.assertDoesNotHaveFile(squashed, 'build/second_file')
|
self.assertDoesNotHaveFile(squashed, 'build/second_file')
|
||||||
|
|
||||||
|
|
||||||
|
def test_tar_empty_layer(self):
|
||||||
|
third_layer = self.create_layer(
|
||||||
|
foo = 'build/first_file',
|
||||||
|
bar = 'build/second_file')
|
||||||
|
|
||||||
|
empty_layer = self.create_layer()
|
||||||
|
|
||||||
|
squashed = self.squash_layers([empty_layer, third_layer])
|
||||||
|
|
||||||
|
self.assertHasFile(squashed, 'build/first_file', 'foo')
|
||||||
|
self.assertHasFile(squashed, 'build/second_file', 'bar')
|
||||||
|
|
||||||
|
|
||||||
|
def test_data_empty_layer(self):
|
||||||
|
third_layer = self.create_layer(
|
||||||
|
foo = 'build/first_file',
|
||||||
|
bar = 'build/second_file')
|
||||||
|
|
||||||
|
empty_layer = self.create_empty_layer()
|
||||||
|
|
||||||
|
squashed = self.squash_layers([empty_layer, third_layer])
|
||||||
|
|
||||||
|
self.assertHasFile(squashed, 'build/first_file', 'foo')
|
||||||
|
self.assertHasFile(squashed, 'build/second_file', 'bar')
|
||||||
|
|
||||||
|
|
||||||
|
def test_broken_layer(self):
|
||||||
|
third_layer = self.create_layer(
|
||||||
|
foo = 'build/first_file',
|
||||||
|
bar = 'build/second_file')
|
||||||
|
|
||||||
|
broken_layer = 'not valid data'
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.squash_layers([broken_layer, third_layer])
|
||||||
|
self.fail('Expected exception')
|
||||||
|
except TarLayerReadException as ex:
|
||||||
|
self.assertEquals('Could not read layer', ex.message)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
import os
|
import os
|
||||||
import tarfile
|
import tarfile
|
||||||
|
|
||||||
|
class TarLayerReadException(Exception):
|
||||||
|
""" Exception raised when reading a layer has failed. """
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TarLayerFormat(object):
|
class TarLayerFormat(object):
|
||||||
""" Class which creates a generator of the combined TAR data. """
|
""" Class which creates a generator of the combined TAR data. """
|
||||||
def __init__(self, tar_iterator):
|
def __init__(self, tar_iterator):
|
||||||
|
@ -10,9 +15,14 @@ class TarLayerFormat(object):
|
||||||
for current_tar in self.tar_iterator():
|
for current_tar in self.tar_iterator():
|
||||||
# Read the current TAR. If it is empty, we just continue
|
# Read the current TAR. If it is empty, we just continue
|
||||||
# to the next one.
|
# to the next one.
|
||||||
|
tar_file = None
|
||||||
try:
|
try:
|
||||||
tar_file = tarfile.open(mode='r|*', fileobj=current_tar)
|
tar_file = tarfile.open(mode='r|*', fileobj=current_tar)
|
||||||
except tarfile.ReadError as re:
|
except tarfile.ReadError as re:
|
||||||
|
if re.message != 'empty file':
|
||||||
|
raise TarLayerReadException('Could not read layer')
|
||||||
|
|
||||||
|
if not tar_file:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# For each of the tar entries, yield them IF and ONLY IF we have not
|
# For each of the tar entries, yield them IF and ONLY IF we have not
|
||||||
|
|
Reference in a new issue