2018-04-16 14:22:25 +00:00
|
|
|
import json
|
|
|
|
import pytest
|
|
|
|
|
2018-12-06 17:40:34 +00:00
|
|
|
from image.docker.schema1 import DockerSchema1Manifest, DOCKER_SCHEMA1_CONTENT_TYPES
|
|
|
|
from image.docker.schema2 import DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE
|
2018-04-16 14:22:25 +00:00
|
|
|
from image.docker.schema2.manifest import DockerSchema2Manifest
|
2018-11-12 21:27:01 +00:00
|
|
|
from image.docker.schema2.list import (MalformedSchema2ManifestList, DockerSchema2ManifestList,
|
|
|
|
DockerSchema2ManifestListBuilder)
|
2018-04-16 14:22:25 +00:00
|
|
|
from image.docker.schema2.test.test_manifest import MANIFEST_BYTES as v22_bytes
|
2018-11-19 09:55:52 +00:00
|
|
|
from image.docker.schemautil import ContentRetrieverForTesting
|
2018-04-16 14:22:25 +00:00
|
|
|
from image.docker.test.test_schema1 import MANIFEST_BYTES as v21_bytes
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('json_data', [
|
|
|
|
'',
|
|
|
|
'{}',
|
|
|
|
"""
|
|
|
|
{
|
|
|
|
"unknown": "key"
|
|
|
|
}
|
|
|
|
""",
|
|
|
|
])
|
|
|
|
def test_malformed_manifest_lists(json_data):
|
|
|
|
with pytest.raises(MalformedSchema2ManifestList):
|
|
|
|
DockerSchema2ManifestList(json_data)
|
|
|
|
|
|
|
|
|
|
|
|
MANIFESTLIST_BYTES = json.dumps({
|
|
|
|
"schemaVersion": 2,
|
|
|
|
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
|
|
|
|
"manifests": [
|
|
|
|
{
|
|
|
|
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
2018-11-14 11:21:50 +00:00
|
|
|
"size": 946,
|
2018-04-16 14:22:25 +00:00
|
|
|
"digest": "sha256:e6",
|
|
|
|
"platform": {
|
|
|
|
"architecture": "ppc64le",
|
|
|
|
"os": "linux",
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"mediaType": "application/vnd.docker.distribution.manifest.v1+json",
|
|
|
|
"size": 878,
|
|
|
|
"digest": "sha256:5b",
|
|
|
|
"platform": {
|
|
|
|
"architecture": "amd64",
|
|
|
|
"os": "linux",
|
|
|
|
"features": [
|
|
|
|
"sse4"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
})
|
|
|
|
|
2018-11-13 08:40:57 +00:00
|
|
|
NO_AMD_MANIFESTLIST_BYTES = json.dumps({
|
|
|
|
"schemaVersion": 2,
|
|
|
|
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
|
|
|
|
"manifests": [
|
|
|
|
{
|
|
|
|
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
2018-11-14 11:21:50 +00:00
|
|
|
"size": 946,
|
2018-11-13 08:40:57 +00:00
|
|
|
"digest": "sha256:e6",
|
|
|
|
"platform": {
|
|
|
|
"architecture": "ppc64le",
|
|
|
|
"os": "linux",
|
|
|
|
}
|
|
|
|
},
|
|
|
|
]
|
|
|
|
})
|
|
|
|
|
2018-11-19 09:55:52 +00:00
|
|
|
retriever = ContentRetrieverForTesting({
|
|
|
|
'sha256:e6': v22_bytes,
|
|
|
|
'sha256:5b': v21_bytes,
|
|
|
|
})
|
2018-04-16 14:22:25 +00:00
|
|
|
|
2018-11-19 09:55:52 +00:00
|
|
|
def test_valid_manifestlist():
|
2018-04-16 14:22:25 +00:00
|
|
|
manifestlist = DockerSchema2ManifestList(MANIFESTLIST_BYTES)
|
2018-11-19 09:55:52 +00:00
|
|
|
assert len(manifestlist.manifests(retriever)) == 2
|
2018-11-12 21:27:01 +00:00
|
|
|
|
|
|
|
assert manifestlist.media_type == 'application/vnd.docker.distribution.manifest.list.v2+json'
|
|
|
|
assert manifestlist.bytes == MANIFESTLIST_BYTES
|
|
|
|
assert manifestlist.manifest_dict == json.loads(MANIFESTLIST_BYTES)
|
2018-11-26 15:58:48 +00:00
|
|
|
assert manifestlist.get_layers(retriever) is None
|
2018-11-19 10:24:04 +00:00
|
|
|
assert not manifestlist.blob_digests
|
2018-04-16 14:22:25 +00:00
|
|
|
|
2018-11-19 09:55:52 +00:00
|
|
|
for index, manifest in enumerate(manifestlist.manifests(retriever)):
|
2018-04-16 14:22:25 +00:00
|
|
|
if index == 0:
|
|
|
|
assert isinstance(manifest.manifest_obj, DockerSchema2Manifest)
|
|
|
|
assert manifest.manifest_obj.schema_version == 2
|
|
|
|
else:
|
|
|
|
assert isinstance(manifest.manifest_obj, DockerSchema1Manifest)
|
|
|
|
assert manifest.manifest_obj.schema_version == 1
|
|
|
|
|
2018-12-06 17:40:34 +00:00
|
|
|
# Check retrieval of a schema 2 manifest. This should return None, because the schema 2 manifest
|
|
|
|
# is not amd64-compatible.
|
|
|
|
schema2_manifest = manifestlist.convert_manifest([DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE], 'foo',
|
|
|
|
'bar', 'baz', retriever)
|
|
|
|
assert schema2_manifest is None
|
|
|
|
|
|
|
|
# Check retrieval of a schema 1 manifest.
|
2018-11-21 15:23:52 +00:00
|
|
|
compatible_manifest = manifestlist.get_schema1_manifest('foo', 'bar', 'baz', retriever)
|
2018-11-13 08:40:57 +00:00
|
|
|
assert compatible_manifest.schema_version == 1
|
2018-11-12 21:27:01 +00:00
|
|
|
|
2018-12-06 17:40:34 +00:00
|
|
|
schema1_manifest = manifestlist.convert_manifest(DOCKER_SCHEMA1_CONTENT_TYPES, 'foo',
|
|
|
|
'bar', 'baz', retriever)
|
|
|
|
assert schema1_manifest.schema_version == 1
|
|
|
|
assert schema1_manifest.digest == compatible_manifest.digest
|
|
|
|
|
2018-11-12 21:27:01 +00:00
|
|
|
|
2018-11-21 15:23:52 +00:00
|
|
|
def test_get_schema1_manifest_no_matching_list():
|
2018-11-13 08:40:57 +00:00
|
|
|
manifestlist = DockerSchema2ManifestList(NO_AMD_MANIFESTLIST_BYTES)
|
2018-11-19 09:55:52 +00:00
|
|
|
assert len(manifestlist.manifests(retriever)) == 1
|
2018-11-13 08:40:57 +00:00
|
|
|
|
|
|
|
assert manifestlist.media_type == 'application/vnd.docker.distribution.manifest.list.v2+json'
|
|
|
|
assert manifestlist.bytes == NO_AMD_MANIFESTLIST_BYTES
|
|
|
|
|
2018-11-21 15:23:52 +00:00
|
|
|
compatible_manifest = manifestlist.get_schema1_manifest('foo', 'bar', 'baz', retriever)
|
2018-11-13 08:40:57 +00:00
|
|
|
assert compatible_manifest is None
|
|
|
|
|
|
|
|
|
2018-11-12 21:27:01 +00:00
|
|
|
def test_builder():
|
|
|
|
existing = DockerSchema2ManifestList(MANIFESTLIST_BYTES)
|
|
|
|
builder = DockerSchema2ManifestListBuilder()
|
2018-11-19 09:55:52 +00:00
|
|
|
for index, manifest in enumerate(existing.manifests(retriever)):
|
2018-11-12 21:27:01 +00:00
|
|
|
builder.add_manifest(manifest.manifest_obj, "amd64", "os")
|
|
|
|
|
|
|
|
built = builder.build()
|
2018-11-19 09:55:52 +00:00
|
|
|
assert len(built.manifests(retriever)) == 2
|