def test_connect_existing_manifest_to_manifest_list(self, create_repo): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) input_manifest = parse_manifest_from_bytes( Bytes.for_string_or_unicode(UBI8_LATEST_MANIFEST_SCHEMA2), DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE, ) proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest, _ = proxy_model._create_manifest_with_temp_tag( repo_ref, input_manifest) assert manifest is not None input_list = parse_manifest_from_bytes( Bytes.for_string_or_unicode(UBI8_LATEST_MANIFEST_LIST), DOCKER_SCHEMA2_MANIFESTLIST_CONTENT_TYPE, sparse_manifest_support=True, ) manifest_list, _ = proxy_model._create_manifest_and_retarget_tag( repo_ref, input_list, self.tag) assert manifest_list is not None conn_count = (ManifestChild.select().where( ManifestChild.manifest == manifest_list.id, ManifestChild.child_manifest == manifest.id, ).count()) assert conn_count == 1
def test_create_placeholder_blobs_for_new_manifest(self, create_repo): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) input_manifest = parse_manifest_from_bytes( Bytes.for_string_or_unicode(UBI8_8_4_MANIFEST_SCHEMA2), DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE, ) proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest, _ = proxy_model._create_manifest_and_retarget_tag( repo_ref, input_manifest, self.tag) assert manifest is not None blob_count = 1 # schema 2 manifests have one extra config blob blob_count += len(input_manifest.manifest_dict["layers"]) mblobs = ManifestBlob.select().where( ManifestBlob.manifest == manifest.id) assert blob_count == mblobs.count() expected_digests = [ layer["digest"] for layer in input_manifest.manifest_dict["layers"] ] expected_digests.append(input_manifest.config.digest) created_digests = [mblob.blob.content_checksum for mblob in mblobs] assert sorted(expected_digests) == sorted(created_digests)
def test_returns_cached_manifest_when_it_exists_upstream( self, create_repo, proxy_manifest_response): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) proxy_mock = proxy_manifest_response( UBI8_8_4_DIGEST, UBI8_8_4_MANIFEST_SCHEMA2, DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest = proxy_model.lookup_manifest_by_digest( repo_ref, UBI8_8_4_DIGEST) assert manifest is not None assert manifest.digest == UBI8_8_4_DIGEST first_manifest = manifest with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): manifest = proxy_model.lookup_manifest_by_digest( repo_ref, UBI8_8_4_DIGEST) assert manifest is not None assert manifest.id == first_manifest.id assert manifest.digest == first_manifest.digest # one for each lookup_manifest_by_digest call assert proxy_mock.manifest_exists.call_count == 2 # single call from first call to lookup_manifest_by_digest assert proxy_mock.get_manifest.call_count == 1
def test_bumps_tag_expiration_when_upstream_is_alive_and_cache_is_up_to_date( self, create_repo, proxy_manifest_response): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) proxy_mock = proxy_manifest_response( self.tag, UBI8_8_5_MANIFEST_SCHEMA2, DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) tag = proxy_model.get_repo_tag(repo_ref, self.tag) assert tag is not None assert tag.name == self.tag first_tag = tag with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): tag = proxy_model.get_repo_tag(repo_ref, self.tag) assert tag is not None assert tag.lifetime_end_ms > first_tag.lifetime_end_ms
def test_renew_tag_when_manifest_is_cached_and_exists_upstream( self, create_repo, proxy_manifest_response): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) proxy_mock = proxy_manifest_response( UBI8_8_4_DIGEST, UBI8_8_4_MANIFEST_SCHEMA2, DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest = proxy_model.lookup_manifest_by_digest( repo_ref, UBI8_8_4_DIGEST) assert manifest is not None first_tag = oci.tag.get_tag_by_manifest_id(repo_ref.id, manifest.id) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): manifest = proxy_model.lookup_manifest_by_digest( repo_ref, UBI8_8_4_DIGEST) assert manifest is not None tag = oci.tag.get_tag_by_manifest_id(repo_ref.id, manifest.id) assert tag.lifetime_end_ms > first_tag.lifetime_end_ms
def test_create_8_4_tag_for_existing_manifest(self, create_repo): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) input_manifest = parse_manifest_from_bytes( Bytes.for_string_or_unicode(UBI8_8_4_MANIFEST_SCHEMA2), DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE, ) proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) # first create the manifest with a temp tag first_manifest, _ = proxy_model._create_manifest_with_temp_tag( repo_ref, input_manifest) # now try to create it again, but using the actual tag manifest, tag = proxy_model._create_manifest_and_retarget_tag( repo_ref, input_manifest, self.tag) assert first_manifest is not None assert manifest is not None assert tag is not None assert manifest.internal_manifest_bytes.as_unicode( ) == UBI8_8_4_MANIFEST_SCHEMA2 assert manifest.digest == UBI8_8_4_DIGEST assert manifest.id == first_manifest.id
def test_create_temp_tags_for_newly_created_sub_manifests_on_manifest_list( self, create_repo): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) input_manifest = parse_manifest_from_bytes( Bytes.for_string_or_unicode(UBI8_LATEST_MANIFEST_LIST), DOCKER_SCHEMA2_MANIFESTLIST_CONTENT_TYPE, sparse_manifest_support=True, ) proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest, _ = proxy_model._create_manifest_and_retarget_tag( repo_ref, input_manifest, self.tag) mchildren = ManifestChild.select( ManifestChild.child_manifest_id).where( ManifestChild.manifest == manifest.id) tags = Tag.select().join( ManifestChild, on=(Tag.manifest_id == ManifestChild.child_manifest_id)) assert mchildren.count() == tags.count() assert all([t.hidden for t in tags]), "all sub manifest tags must be hidden" assert all( [t.name != self.tag for t in tags] ), "sub manifest tags must have temp tag name, not parent manifest name"
def test_passes_through_upstream_error_when_image_isnt_cached( self, create_repo, proxy_manifest_response): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) proxy_mock = proxy_manifest_response("not-existing-ref", "", "") with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) with pytest.raises(TagDoesNotExist): proxy_model.get_repo_tag(repo_ref, self.tag)
def test_raises_exception_with_docker_v2_manifest_to_v1(self): def get_blob(layer): content = Bytes.for_string_or_unicode(layer).as_encoded_str() digest = str(sha256_digest(content)) blob = store_blob_record_and_temp_link( self.orgname, self.upstream_repository, digest, ImageStorageLocation.get(name="local_us"), len(content), 120, ) storage.put_content(["local_us"], get_layer_path(blob), content) return blob, digest layer1 = json.dumps({ "config": {}, "rootfs": { "type": "layers", "diff_ids": [] }, "history": [{}], }) _, config_digest = get_blob(layer1) layer2 = "hello world" _, blob_digest = get_blob(layer2) builder = DockerSchema2ManifestBuilder() builder.set_config_digest(config_digest, len(layer1.encode("utf-8"))) builder.add_layer(blob_digest, len(layer2.encode("utf-8"))) manifest = builder.build() created_manifest = get_or_create_manifest(self.repo_ref.id, manifest, storage) assert created_manifest is not None proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) m = ManifestType.for_manifest(created_manifest.manifest, MagicMock()) with pytest.raises(ManifestException): proxy_model.get_schema1_parsed_manifest( m, self.orgname, self.upstream_repository, self.tag, storage, raise_on_error=True, )
def setup(self, client, app): self.client = client self.user = model.user.get_user("devtable") context, subject = build_context_and_subject( ValidatedAuthContext(user=self.user)) access = [{ "type": "repository", "name": self.repository, "actions": ["pull"], }] token = generate_bearer_token(realapp.config["SERVER_HOSTNAME"], subject, context, access, 600, instance_keys) self.headers = { "Authorization": f"Bearer {token.decode('ascii')}", } try: model.organization.get(self.org) except Exception: org = model.organization.create_organization( self.org, "*****@*****.**", self.user) org.save() if self.config is None: self.config = model.proxy_cache.create_proxy_cache_config( org_name=self.org, upstream_registry=self.registry, expiration_s=3600, ) if self.repo_ref is None: r = model.repository.create_repository(self.org, self.image_name, self.user) assert r is not None self.repo_ref = registry_model.lookup_repository( self.org, self.image_name) assert self.repo_ref is not None if self.blob_digest is None: proxy_model = ProxyModel(self.org, self.image_name, self.user) manifest = proxy_model.lookup_manifest_by_digest( self.repo_ref, self.manifest_digest) self.blob_digest = manifest.get_parsed_manifest().blob_digests[0]
def test_raises_exception_with_manifest_list(self): manifest = parse_manifest_from_bytes( Bytes.for_string_or_unicode(UBI8_LATEST_MANIFEST_LIST), DOCKER_SCHEMA2_MANIFESTLIST_CONTENT_TYPE, ) proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) with pytest.raises(ManifestException): proxy_model.get_schema1_parsed_manifest( manifest, self.orgname, self.upstream_repository, self.tag, storage, raise_on_error=True, )
def test_caches_manifest_on_first_pull(self, create_repo, proxy_manifest_response): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) proxy_mock = proxy_manifest_response( self.tag, UBI8_8_4_MANIFEST_SCHEMA2, DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) tag = proxy_model.get_repo_tag(repo_ref, self.tag) assert tag is not None assert tag.manifest is not None assert tag.manifest.internal_manifest_bytes.as_unicode( ) == UBI8_8_4_MANIFEST_SCHEMA2
def test_create_manifest_and_temp_tag_when_they_dont_exist( self, create_repo): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) input_manifest = parse_manifest_from_bytes( Bytes.for_string_or_unicode(UBI8_8_4_MANIFEST_SCHEMA2), DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE, ) proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest, tag = proxy_model._create_manifest_and_retarget_tag( repo_ref, input_manifest, self.tag) assert manifest is not None assert tag is not None assert manifest.internal_manifest_bytes.as_unicode( ) == UBI8_8_4_MANIFEST_SCHEMA2 assert manifest.digest == UBI8_8_4_DIGEST
def test_renews_expired_tag_when_manifest_is_up_to_date_with_upstream( self, create_repo, proxy_manifest_response): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) proxy_mock = proxy_manifest_response( self.tag, UBI8_8_5_MANIFEST_SCHEMA2, DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) tag = proxy_model.get_repo_tag(repo_ref, self.tag) assert tag is not None assert tag.name == self.tag # expire the tag by setting start and end time to the past before_ms = get_epoch_timestamp_ms() - timedelta( hours=24).total_seconds() * 1000 Tag.update( lifetime_start_ms=before_ms, lifetime_end_ms=before_ms + 5, ).where(Tag.id == tag.id).execute() expired_tag = tag with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): tag = proxy_model.get_repo_tag(repo_ref, self.tag) assert tag is not None assert expired_tag.id == tag.id assert expired_tag.manifest.id == tag.manifest.id assert not tag.expired new_expiration_ms = get_epoch_timestamp_ms( ) + self.config.expiration_s * 1000 # subtract a some milliseconds so the test doesn't flake assert tag.lifetime_end_ms >= new_expiration_ms - 500
def test_create_sub_manifests_for_manifest_list(self, create_repo): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) input_manifest = parse_manifest_from_bytes( Bytes.for_string_or_unicode(UBI8_LATEST_MANIFEST_LIST), DOCKER_SCHEMA2_MANIFESTLIST_CONTENT_TYPE, sparse_manifest_support=True, ) proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest, _ = proxy_model._create_manifest_and_retarget_tag( repo_ref, input_manifest, self.tag) mchildren = ManifestChild.select().where( ManifestChild.manifest == manifest.id) created_count = mchildren.count() expected_count = len( list(input_manifest.child_manifests(content_retriever=None))) assert expected_count == created_count
def test_does_not_bump_tag_expiration_when_manifest_is_cached_and_upstream_errors( self, create_repo, proxy_manifest_response): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) proxy_mock = proxy_manifest_response( UBI8_8_4_DIGEST, UBI8_8_4_MANIFEST_SCHEMA2, DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest = proxy_model.lookup_manifest_by_digest( repo_ref, UBI8_8_4_DIGEST) assert manifest is not None first_tag = Tag.get(manifest_id=manifest.id) proxy_mock = proxy_manifest_response("not-existing-ref", "", "") with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest = proxy_model.lookup_manifest_by_digest( repo_ref, UBI8_8_4_DIGEST) assert manifest is not None tag = Tag.get(manifest_id=manifest.id) assert tag.id == first_tag.id assert tag.lifetime_end_ms == first_tag.lifetime_end_ms
def test_returns_cached_manifest_when_upstream_errors_and_cache_is_not_expired( self, create_repo, proxy_manifest_response): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) proxy_mock = proxy_manifest_response( UBI8_8_4_DIGEST, UBI8_8_4_MANIFEST_SCHEMA2, DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest = proxy_model.lookup_manifest_by_digest( repo_ref, UBI8_8_4_DIGEST) assert manifest is not None assert manifest.digest == UBI8_8_4_DIGEST first_manifest = manifest proxy_mock = proxy_manifest_response("not-existing-ref", "", "") with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest = proxy_model.lookup_manifest_by_digest( repo_ref, UBI8_8_4_DIGEST) assert manifest is not None assert manifest.id == first_manifest.id assert manifest.digest == first_manifest.digest assert proxy_mock.manifest_exists.call_count == 1 assert proxy_mock.get_manifest.call_count == 0
def test_return_None_when_manifest_is_placeholder_and_upstream_is_down( self, create_repo, proxy_manifest_response): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) proxy_mock = proxy_manifest_response( "latest", UBI8_LATEST_MANIFEST_LIST, DOCKER_SCHEMA2_MANIFESTLIST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) tag = proxy_model.get_repo_tag(repo_ref, "latest") assert tag is not None assert tag.manifest is not None proxy_mock = proxy_manifest_response("does-not-exist", "", "") with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest = proxy_model.lookup_manifest_by_digest( repo_ref, UBI8_LATEST_DIGEST) assert manifest is None
def test_update_relevant_manifest_fields_when_manifest_is_placeholder( self, create_repo, proxy_manifest_response): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) proxy_mock = proxy_manifest_response( "latest", UBI8_LATEST_MANIFEST_LIST, DOCKER_SCHEMA2_MANIFESTLIST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) tag = proxy_model.get_repo_tag(repo_ref, "latest") assert tag is not None assert tag.manifest.digest == UBI8_LATEST_MANIFEST_LIST_DIGEST assert tag.manifest.is_manifest_list proxy_mock = proxy_manifest_response( UBI8_LATEST_DIGEST, UBI8_LATEST_MANIFEST_SCHEMA2, DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest = proxy_model.lookup_manifest_by_digest( repo_ref, UBI8_LATEST_DIGEST) mbytes = manifest.internal_manifest_bytes.as_unicode() assert mbytes != "" assert manifest.digest == UBI8_LATEST_DIGEST assert manifest.layers_compressed_size == 772795
def test_returns_None_when_manifest_no_longer_exists_upstream_and_local_cache_is_expired( self, create_repo, proxy_manifest_response): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) proxy_mock = proxy_manifest_response( self.tag, UBI8_8_5_MANIFEST_SCHEMA2, DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) tag = proxy_model.get_repo_tag(repo_ref, self.tag) assert tag is not None # expire the tag by setting start and end time to the past before_ms = get_epoch_timestamp_ms() - timedelta( hours=24).total_seconds() * 1000 Tag.update( lifetime_start_ms=before_ms, lifetime_end_ms=before_ms + 5, ).where(Tag.id == tag.id).execute() proxy_mock = proxy_manifest_response("not-existing-ref", "", "") with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) tag = proxy_model.get_repo_tag(repo_ref, self.tag) assert tag is None
def test_doesnt_bump_tag_expiration_when_upstream_is_dead( self, create_repo, proxy_manifest_response): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) proxy_mock = proxy_manifest_response( self.tag, UBI8_8_5_MANIFEST_SCHEMA2, DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) tag = proxy_model.get_repo_tag(repo_ref, self.tag) assert tag is not None first_tag = tag proxy_mock = proxy_manifest_response("not-existing-ref", "", "") with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) tag = proxy_model.get_repo_tag(repo_ref, self.tag) assert tag is not None assert tag.lifetime_end_ms == first_tag.lifetime_end_ms
def test_connect_existing_blobs_to_new_manifest(self, create_repo): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) input_manifest = parse_manifest_from_bytes( Bytes.for_string_or_unicode(UBI8_8_4_MANIFEST_SCHEMA2), DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE, ) layer = input_manifest.manifest_dict["layers"][0] blob = ImageStorage.create( image_size=layer["size"], uncompressed_size=layer["size"], content_checksum=layer["digest"], ) proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) proxy_model._create_manifest_and_retarget_tag(repo_ref, input_manifest, self.tag) blob_count = (ImageStorage.select().where( ImageStorage.content_checksum == blob.content_checksum).count()) assert blob_count == 1
def test_registry_proxy_model_init_only_query_db_once(initialized_db): orgname = "testorg" user = get_user("devtable") org = create_organization(orgname, "{self.orgname}@devtable.com", user) org.save() create_proxy_cache_config( org_name=orgname, upstream_registry="quay.io", expiration_s=3600, ) with assert_query_count(1): ProxyModel( orgname, "app-sre/ubi8-ubi", user, )
def test_renew_manifest_and_parent_tag_when_manifest_is_child_of_manifest_list( self, create_repo, proxy_manifest_response): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) input_list = parse_manifest_from_bytes( Bytes.for_string_or_unicode(UBI8_LATEST_MANIFEST_LIST), DOCKER_SCHEMA2_MANIFESTLIST_CONTENT_TYPE, sparse_manifest_support=True, ) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock()): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest_list, tag = proxy_model._create_manifest_and_retarget_tag( repo_ref, input_list, "latest") assert manifest_list is not None child = (ManifestChild.select(ManifestChild.child_manifest_id).join( Manifest, on=(ManifestChild.child_manifest_id == Manifest.id )).where((ManifestChild.manifest_id == manifest_list.id) & (Manifest.digest == UBI8_LATEST_DIGEST))) manifest_tag = Tag.select().where(Tag.manifest == child).get() manifest_list_tag = tag proxy_mock = proxy_manifest_response( UBI8_LATEST_DIGEST, UBI8_LATEST_MANIFEST_SCHEMA2, DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest = proxy_model.lookup_manifest_by_digest( repo_ref, UBI8_LATEST_DIGEST) updated_tag = oci.tag.get_tag_by_manifest_id(repo_ref.id, manifest.id) updated_list_tag = oci.tag.get_tag_by_manifest_id( repo_ref.id, manifest_list.id) assert updated_tag.id == manifest_tag.id assert updated_list_tag.id == manifest_list_tag.id assert updated_tag.lifetime_end_ms > manifest_tag.lifetime_end_ms assert updated_list_tag.lifetime_end_ms > manifest_list_tag.lifetime_end_ms
def test_renew_tag_when_cache_is_expired_and_manifest_is_up_to_date_with_upstream( self, create_repo, proxy_manifest_response): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) proxy_mock = proxy_manifest_response( UBI8_8_4_DIGEST, UBI8_8_4_MANIFEST_SCHEMA2, DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest = proxy_model.lookup_manifest_by_digest( repo_ref, UBI8_8_4_DIGEST) assert manifest is not None before_ms = get_epoch_timestamp_ms() - timedelta( hours=24).total_seconds() * 1000 Tag.update( lifetime_start_ms=before_ms, lifetime_end_ms=before_ms + 5, ).where(Tag.manifest == manifest.id).execute() with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) manifest = proxy_model.lookup_manifest_by_digest( repo_ref, UBI8_8_4_DIGEST) assert manifest is not None tag = Tag.get(manifest_id=manifest.id) now_ms = get_epoch_timestamp_ms() assert tag.lifetime_end_ms > now_ms
def test_updates_manifest_and_bumps_tag_expiration_when_upstream_manifest_changed( self, create_repo, proxy_manifest_response): repo_ref = create_repo(self.orgname, self.upstream_repository, self.user) proxy_mock = proxy_manifest_response( self.tag, UBI8_8_4_MANIFEST_SCHEMA2, DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) tag = proxy_model.get_repo_tag(repo_ref, self.tag) assert tag is not None assert tag.name == self.tag first_manifest = tag.manifest proxy_mock = proxy_manifest_response( self.tag, UBI8_8_5_MANIFEST_SCHEMA2, DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE) with patch("data.registry_model.registry_proxy_model.Proxy", MagicMock(return_value=proxy_mock)): proxy_model = ProxyModel( self.orgname, self.upstream_repository, self.user, ) tag = proxy_model.get_repo_tag(repo_ref, self.tag) assert tag is not None assert tag.name == self.tag assert tag.manifest.id != first_manifest.id assert tag.manifest.digest == UBI8_8_5_DIGEST