Add tests for manifest lists and fix some issues encountered while testing

This commit is contained in:
Joseph Schorr 2018-11-13 19:05:45 +02:00
parent 9994f0ae61
commit 7a794e29c0
9 changed files with 311 additions and 98 deletions

View file

@ -20,6 +20,7 @@ from test.registry.protocols import Failures, Image, layer_bytes_for_contents, P
from app import instance_keys
from data.model.tag import list_repository_tags
from image.docker.schema1 import DOCKER_SCHEMA1_MANIFEST_CONTENT_TYPE
from image.docker.schema2.list import DockerSchema2ManifestListBuilder
from util.security.registry_jwt import decode_bearer_header
from util.timedeltastring import convert_to_timedelta
@ -613,10 +614,10 @@ def test_unsupported_manifest_content_type(content_type, manifest_protocol, basi
@pytest.mark.parametrize('accept_mimetypes', [
[('application/vnd.oci.image.manifest.v1+json', 1)],
[('application/vnd.docker.distribution.manifest.v2+json', 1),
('application/vnd.docker.distribution.manifest.list.v2+json', 1)],
[('application/vnd.foo.bar', 1)],
['application/vnd.oci.image.manifest.v1+json'],
['application/vnd.docker.distribution.manifest.v2+json',
'application/vnd.docker.distribution.manifest.list.v2+json'],
['application/vnd.foo.bar'],
])
def test_unsupported_manifest_accept_headers(accept_mimetypes, manifest_protocol, basic_images,
data_model, liveserver_session, app_reloader):
@ -629,7 +630,7 @@ def test_unsupported_manifest_accept_headers(accept_mimetypes, manifest_protocol
options = ProtocolOptions()
options.manifest_content_type = DOCKER_SCHEMA1_MANIFEST_CONTENT_TYPE
options.accept_mimetypes = str(Accept(accept_mimetypes))
options.accept_mimetypes = accept_mimetypes
# Attempt to push a new repository.
manifest_protocol.push(liveserver_session, 'devtable', 'newrepo', 'latest', basic_images,
@ -1356,3 +1357,96 @@ def test_push_tag_existing_image(v1_protocol, puller, basic_images, liveserver_s
# Pull the repository to verify.
puller.pull(liveserver_session, 'devtable', 'newrepo', 'anothertag', basic_images,
credentials=credentials)
@pytest.mark.parametrize('schema_version', [
1,
2,
])
@pytest.mark.parametrize('is_amd', [
True,
False
])
def test_push_pull_manifest_list_back_compat(v22_protocol, v2_protocol, basic_images,
different_images, liveserver_session, app_reloader,
schema_version, data_model, is_amd):
""" Test: Push a new tag with a manifest list containing two manifests, one (possibly) legacy
and one not, and, if there is a legacy manifest, ensure it can be pulled.
"""
if data_model != 'oci_model':
return
credentials = ('devtable', 'password')
options = ProtocolOptions()
# Build the manifests that will go in the list.
blobs = {}
signed = v22_protocol.build_schema1('devtable', 'newrepo', 'latest', basic_images, blobs, options)
first_manifest = signed.unsigned()
if schema_version == 2:
first_manifest = v22_protocol.build_schema2(basic_images, blobs, options)
second_manifest = v22_protocol.build_schema2(different_images, blobs, options)
# Add the manifests themselves to the blobs map.
blobs[str(first_manifest.digest)] = first_manifest.bytes
blobs[str(second_manifest.digest)] = second_manifest.bytes
# Create and push the manifest list.
builder = DockerSchema2ManifestListBuilder()
builder.add_manifest(first_manifest, 'amd64' if is_amd else 'something', 'linux')
builder.add_manifest(second_manifest, 'arm', 'linux')
manifestlist = builder.build()
v22_protocol.push_list(liveserver_session, 'devtable', 'newrepo', 'latest', manifestlist, blobs,
credentials=credentials, options=options)
# Pull the tag and ensure we (don't) get back the basic images, since they are(n't) part of the
# amd64+linux manifest.
v2_protocol.pull(liveserver_session, 'devtable', 'newrepo', 'latest', basic_images,
credentials=credentials,
expected_failure=Failures.UNKNOWN_TAG if not is_amd else None)
@pytest.mark.parametrize('schema_version', [
1,
2,
])
def test_push_pull_manifest_list(v22_protocol, basic_images, different_images, liveserver_session,
app_reloader, schema_version, data_model):
""" Test: Push a new tag with a manifest list containing two manifests, one (possibly) legacy
and one not, and pull it.
"""
if data_model != 'oci_model':
return
credentials = ('devtable', 'password')
options = ProtocolOptions()
# Build the manifests that will go in the list.
blobs = {}
signed = v22_protocol.build_schema1('devtable', 'newrepo', 'latest', basic_images, blobs, options)
first_manifest = signed.unsigned()
if schema_version == 2:
first_manifest = v22_protocol.build_schema2(basic_images, blobs, options)
second_manifest = v22_protocol.build_schema2(different_images, blobs, options)
# Add the manifests themselves to the blobs map.
blobs[str(first_manifest.digest)] = first_manifest.bytes
blobs[str(second_manifest.digest)] = second_manifest.bytes
# Create and push the manifest list.
builder = DockerSchema2ManifestListBuilder()
builder.add_manifest(first_manifest, 'amd64', 'linux')
builder.add_manifest(second_manifest, 'arm', 'linux')
manifestlist = builder.build()
v22_protocol.push_list(liveserver_session, 'devtable', 'newrepo', 'latest', manifestlist, blobs,
credentials=credentials, options=options)
# Pull and verify the manifest list.
v22_protocol.pull_list(liveserver_session, 'devtable', 'newrepo', 'latest', manifestlist,
credentials=credentials, options=options)