Add additional multi-layer complex squashing test
This commit is contained in:
parent
f252b0b16f
commit
7424a6d73a
3 changed files with 99 additions and 3 deletions
|
@ -37,6 +37,45 @@ def sized_images():
|
|||
]
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def multi_layer_images():
|
||||
""" Returns complex images (with sizes) for push and pull testing. """
|
||||
# Note: order is from base layer down to leaf.
|
||||
layer1_bytes = layer_bytes_for_contents('layer 1 contents', mode='', other_files={
|
||||
'file1': 'from-layer-1',
|
||||
})
|
||||
|
||||
layer2_bytes = layer_bytes_for_contents('layer 2 contents', mode='', other_files={
|
||||
'file2': 'from-layer-2',
|
||||
})
|
||||
|
||||
layer3_bytes = layer_bytes_for_contents('layer 3 contents', mode='', other_files={
|
||||
'file1': 'from-layer-3',
|
||||
'file3': 'from-layer-3',
|
||||
})
|
||||
|
||||
layer4_bytes = layer_bytes_for_contents('layer 4 contents', mode='', other_files={
|
||||
'file3': 'from-layer-4',
|
||||
})
|
||||
|
||||
layer5_bytes = layer_bytes_for_contents('layer 5 contents', mode='', other_files={
|
||||
'file4': 'from-layer-5',
|
||||
})
|
||||
|
||||
return [
|
||||
Image(id='layer1', bytes=layer1_bytes, parent_id=None, size=len(layer1_bytes),
|
||||
config={'internal_id': 'layer1'}),
|
||||
Image(id='layer2', bytes=layer2_bytes, parent_id='layer1', size=len(layer2_bytes),
|
||||
config={'internal_id': 'layer2'}),
|
||||
Image(id='layer3', bytes=layer3_bytes, parent_id='layer2', size=len(layer3_bytes),
|
||||
config={'internal_id': 'layer3'}),
|
||||
Image(id='layer4', bytes=layer4_bytes, parent_id='layer3', size=len(layer4_bytes),
|
||||
config={'internal_id': 'layer4'}),
|
||||
Image(id='someid', bytes=layer5_bytes, parent_id='layer4', size=len(layer5_bytes),
|
||||
config={'internal_id': 'layer5'}),
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def jwk():
|
||||
return RSAKey(key=RSA.generate(2048))
|
||||
|
|
|
@ -14,8 +14,9 @@ PushResult = namedtuple('PushResult', ['checksums', 'manifests', 'headers'])
|
|||
PullResult = namedtuple('PullResult', ['manifests', 'image_ids'])
|
||||
|
||||
|
||||
def layer_bytes_for_contents(contents, mode='|gz'):
|
||||
def layer_bytes_for_contents(contents, mode='|gz', other_files=None):
|
||||
layer_data = StringIO()
|
||||
tar_file = tarfile.open(fileobj=layer_data, mode='w' + mode)
|
||||
|
||||
def add_file(name, contents):
|
||||
tar_file_info = tarfile.TarInfo(name=name)
|
||||
|
@ -23,12 +24,16 @@ def layer_bytes_for_contents(contents, mode='|gz'):
|
|||
tar_file_info.size = len(contents)
|
||||
tar_file_info.mtime = 1
|
||||
|
||||
tar_file = tarfile.open(fileobj=layer_data, mode='w' + mode)
|
||||
tar_file.addfile(tar_file_info, StringIO(contents))
|
||||
tar_file.close()
|
||||
|
||||
add_file('contents', contents)
|
||||
|
||||
if other_files is not None:
|
||||
for file_name, file_contents in other_files.iteritems():
|
||||
add_file(file_name, file_contents)
|
||||
|
||||
tar_file.close()
|
||||
|
||||
layer_bytes = layer_data.getvalue()
|
||||
layer_data.close()
|
||||
return layer_bytes
|
||||
|
|
|
@ -930,6 +930,58 @@ def test_squashed_image_disabled_user(pusher, sized_images, liveserver_session,
|
|||
assert response.status_code == 403
|
||||
|
||||
|
||||
@pytest.mark.parametrize('use_estimates', [
|
||||
False,
|
||||
True,
|
||||
])
|
||||
def test_multilayer_squashed_images(use_estimates, pusher, multi_layer_images, liveserver_session,
|
||||
liveserver, registry_server_executor, app_reloader):
|
||||
""" Test: Pulling of multilayer, complex squashed images. """
|
||||
credentials = ('devtable', 'password')
|
||||
|
||||
# Push an image to download.
|
||||
pusher.push(liveserver_session, 'devtable', 'newrepo', 'latest', multi_layer_images,
|
||||
credentials=credentials)
|
||||
|
||||
if use_estimates:
|
||||
# Clear the uncompressed size stored for the images, to ensure that we estimate instead.
|
||||
for image in multi_layer_images:
|
||||
registry_server_executor.on(liveserver).clear_uncompressed_size(image.id)
|
||||
|
||||
# Pull the squashed version.
|
||||
response = liveserver_session.get('/c1/squash/devtable/newrepo/latest', auth=credentials)
|
||||
tar = tarfile.open(fileobj=StringIO(response.content))
|
||||
|
||||
# Verify the squashed image.
|
||||
expected_image_id = 'cdc6d6c0d07d2cbacfc579e49ce0c256c5084b9b2b16c1b1b0c45f26a12a4ba5'
|
||||
expected_names = ['repositories',
|
||||
expected_image_id,
|
||||
'%s/json' % expected_image_id,
|
||||
'%s/VERSION' % expected_image_id,
|
||||
'%s/layer.tar' % expected_image_id]
|
||||
|
||||
assert tar.getnames() == expected_names
|
||||
|
||||
# Verify the JSON image data.
|
||||
json_data = (tar.extractfile(tar.getmember('%s/json' % expected_image_id)).read())
|
||||
|
||||
# Ensure the JSON loads and parses.
|
||||
result = json.loads(json_data)
|
||||
assert result['id'] == expected_image_id
|
||||
assert result['config']['internal_id'] == 'layer5'
|
||||
|
||||
# Ensure that squashed layer tar can be opened.
|
||||
tar = tarfile.open(fileobj=tar.extractfile(tar.getmember('%s/layer.tar' % expected_image_id)))
|
||||
assert set(tar.getnames()) == {'contents', 'file1', 'file2', 'file3', 'file4'}
|
||||
|
||||
# Check the contents of various files.
|
||||
assert tar.extractfile('contents').read() == 'layer 5 contents'
|
||||
assert tar.extractfile('file1').read() == 'from-layer-3'
|
||||
assert tar.extractfile('file2').read() == 'from-layer-2'
|
||||
assert tar.extractfile('file3').read() == 'from-layer-4'
|
||||
assert tar.extractfile('file4').read() == 'from-layer-5'
|
||||
|
||||
|
||||
@pytest.mark.parametrize('use_estimates', [
|
||||
False,
|
||||
True,
|
||||
|
|
Reference in a new issue