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")
|
@pytest.fixture(scope="session")
|
||||||
def jwk():
|
def jwk():
|
||||||
return RSAKey(key=RSA.generate(2048))
|
return RSAKey(key=RSA.generate(2048))
|
||||||
|
|
|
@ -14,8 +14,9 @@ PushResult = namedtuple('PushResult', ['checksums', 'manifests', 'headers'])
|
||||||
PullResult = namedtuple('PullResult', ['manifests', 'image_ids'])
|
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()
|
layer_data = StringIO()
|
||||||
|
tar_file = tarfile.open(fileobj=layer_data, mode='w' + mode)
|
||||||
|
|
||||||
def add_file(name, contents):
|
def add_file(name, contents):
|
||||||
tar_file_info = tarfile.TarInfo(name=name)
|
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.size = len(contents)
|
||||||
tar_file_info.mtime = 1
|
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.addfile(tar_file_info, StringIO(contents))
|
||||||
tar_file.close()
|
|
||||||
|
|
||||||
add_file('contents', contents)
|
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_bytes = layer_data.getvalue()
|
||||||
layer_data.close()
|
layer_data.close()
|
||||||
return layer_bytes
|
return layer_bytes
|
||||||
|
|
|
@ -930,6 +930,58 @@ def test_squashed_image_disabled_user(pusher, sized_images, liveserver_session,
|
||||||
assert response.status_code == 403
|
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', [
|
@pytest.mark.parametrize('use_estimates', [
|
||||||
False,
|
False,
|
||||||
True,
|
True,
|
||||||
|
|
Reference in a new issue