From 79a08b452e766631713b155e49b1b36b4fc13348 Mon Sep 17 00:00:00 2001 From: Kyle Tarplee Date: Tue, 21 Nov 2023 06:47:31 -0500 Subject: [PATCH] fix: check content-type when using referrers API (#635) When accessing the referrer's API, this adds a check to make sure the content-type is an OCI index. Also fixes the tests to properly set the content-type header in the response. Closes #633 Signed-off-by: Kyle M. Tarplee --- example_copy_test.go | 1 + extendedcopy_test.go | 22 +- registry/remote/example_test.go | 12 ++ registry/remote/repository.go | 37 ++-- registry/remote/repository_test.go | 328 +++++++++++++++++++---------- 5 files changed, 270 insertions(+), 130 deletions(-) diff --git a/example_copy_test.go b/example_copy_test.go index b7e524a9..58ee9f56 100644 --- a/example_copy_test.go +++ b/example_copy_test.go @@ -144,6 +144,7 @@ func TestMain(m *testing.M) { MediaType: ocispec.MediaTypeImageIndex, Manifests: referrers, } + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) if err := json.NewEncoder(w).Encode(result); err != nil { panic(err) } diff --git a/extendedcopy_test.go b/extendedcopy_test.go index 08a0a8c3..2a4c18ad 100644 --- a/extendedcopy_test.go +++ b/extendedcopy_test.go @@ -1031,15 +1031,20 @@ func TestExtendedCopyGraph_FilterAnnotationWithMultipleRegex_Referrers(t *testin // set up test server ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { p := r.URL.Path + var manifests []ocispec.Descriptor switch { case p == "/v2/test/referrers/"+descs[0].Digest.String(): + manifests = descs[1:] + fallthrough + case strings.HasPrefix(p, "/v2/test/referrers/"): result := ocispec.Index{ Versioned: specs.Versioned{ SchemaVersion: 2, // historical value. does not pertain to OCI or docker version }, MediaType: ocispec.MediaTypeImageIndex, - Manifests: descs[1:], + Manifests: manifests, } + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) if err := json.NewEncoder(w).Encode(result); err != nil { t.Errorf("failed to write response: %v", err) } @@ -1076,7 +1081,6 @@ func TestExtendedCopyGraph_FilterAnnotationWithMultipleRegex_Referrers(t *testin default: t.Errorf("unexpected access: %s %s", r.Method, r.URL) w.WriteHeader(http.StatusNotFound) - return } })) defer ts.Close() @@ -1454,15 +1458,20 @@ func TestExtendedCopyGraph_FilterArtifactTypeWithMultipleRegex_Referrers(t *test // set up test server ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { p := r.URL.Path + var manifests []ocispec.Descriptor switch { case p == "/v2/test/referrers/"+descs[0].Digest.String(): + manifests = descs[1:] + fallthrough + case strings.HasPrefix(p, "/v2/test/referrers/"): result := ocispec.Index{ Versioned: specs.Versioned{ SchemaVersion: 2, // historical value. does not pertain to OCI or docker version }, MediaType: ocispec.MediaTypeImageIndex, - Manifests: descs[1:], + Manifests: manifests, } + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) if err := json.NewEncoder(w).Encode(result); err != nil { t.Errorf("failed to write response: %v", err) } @@ -1695,15 +1704,20 @@ func TestExtendedCopyGraph_FilterArtifactTypeAndAnnotationWithMultipleRegex_Refe // set up test server ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { p := r.URL.Path + var manifests []ocispec.Descriptor switch { case p == "/v2/test/referrers/"+descs[0].Digest.String(): + manifests = descs[1:] + fallthrough + case strings.HasPrefix(p, "/v2/test/referrers/"): result := ocispec.Index{ Versioned: specs.Versioned{ SchemaVersion: 2, // historical value. does not pertain to OCI or docker version }, MediaType: ocispec.MediaTypeImageIndex, - Manifests: descs[1:], + Manifests: manifests, } + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) if err := json.NewEncoder(w).Encode(result); err != nil { t.Errorf("failed to write response: %v", err) } diff --git a/registry/remote/example_test.go b/registry/remote/example_test.go index d2fb529d..372ba2ac 100644 --- a/registry/remote/example_test.go +++ b/registry/remote/example_test.go @@ -174,6 +174,17 @@ func TestMain(m *testing.M) { w.Header().Set("Content-Digest", string(blobDescriptor.Digest)) w.Header().Set("Content-Length", strconv.Itoa(len(blobContent))) w.Write([]byte(blobContent)) + case p == fmt.Sprintf("/v2/%s/referrers/%s", exampleRepositoryName, "sha256:0000000000000000000000000000000000000000000000000000000000000000"): + result := ocispec.Index{ + Versioned: specs.Versioned{ + SchemaVersion: 2, // historical value. does not pertain to OCI or docker version + }, + MediaType: ocispec.MediaTypeImageIndex, + } + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) + if err := json.NewEncoder(w).Encode(result); err != nil { + panic(err) + } case p == fmt.Sprintf("/v2/%s/referrers/%s", exampleRepositoryName, exampleManifestDescriptor.Digest.String()): q := r.URL.Query() var referrers []ocispec.Descriptor @@ -191,6 +202,7 @@ func TestMain(m *testing.M) { MediaType: ocispec.MediaTypeImageIndex, Manifests: referrers, } + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) if err := json.NewEncoder(w).Encode(result); err != nil { panic(err) } diff --git a/registry/remote/repository.go b/registry/remote/repository.go index b91054fc..d67240f2 100644 --- a/registry/remote/repository.go +++ b/registry/remote/repository.go @@ -483,18 +483,12 @@ func (r *Repository) Referrers(ctx context.Context, desc ocispec.Descriptor, art // The referrers state is unknown. if err != nil { - var errResp *errcode.ErrorResponse - if !errors.As(err, &errResp) || errResp.StatusCode != http.StatusNotFound { - return err - } - if errutil.IsErrorCode(errResp, errcode.ErrorCodeNameUnknown) { - // The repository is not found, no fallback. - return err + if errors.Is(err, errdef.ErrUnsupported) { + // Referrers API is not supported, fallback to referrers tag schema. + r.SetReferrersCapability(false) + return r.referrersByTagSchema(ctx, desc, artifactType, fn) } - // A 404 returned by Referrers API indicates that Referrers API is - // not supported. Fallback to referrers tag schema. - r.SetReferrersCapability(false) - return r.referrersByTagSchema(ctx, desc, artifactType, fn) + return err } r.SetReferrersCapability(true) @@ -544,10 +538,24 @@ func (r *Repository) referrersPageByAPI(ctx context.Context, artifactType string } defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { + switch resp.StatusCode { + case http.StatusOK: + case http.StatusNotFound: + if errResp := errutil.ParseErrorResponse(resp); errutil.IsErrorCode(errResp, errcode.ErrorCodeNameUnknown) { + // The repository is not found, Referrers API status is unknown + return "", errResp + } + // Referrers API is not supported. + return "", fmt.Errorf("failed to query referrers API: %w", errdef.ErrUnsupported) + default: return "", errutil.ParseErrorResponse(resp) } + // also check the content type + if ct := resp.Header.Get("Content-Type"); ct != ocispec.MediaTypeImageIndex { + return "", fmt.Errorf("unknown content returned (%s), expecting image index: %w", ct, errdef.ErrUnsupported) + } + var index ocispec.Index lr := limitReader(resp.Body, r.MaxMetadataBytes) if err := json.NewDecoder(lr).Decode(&index); err != nil { @@ -657,8 +665,9 @@ func (r *Repository) pingReferrers(ctx context.Context) (bool, error) { switch resp.StatusCode { case http.StatusOK: - r.SetReferrersCapability(true) - return true, nil + supported := resp.Header.Get("Content-Type") == ocispec.MediaTypeImageIndex + r.SetReferrersCapability(supported) + return supported, nil case http.StatusNotFound: if err := errutil.ParseErrorResponse(resp); errutil.IsErrorCode(err, errcode.ErrorCodeNameUnknown) { // repository not found diff --git a/registry/remote/repository_test.go b/registry/remote/repository_test.go index b6772cbd..b66aec46 100644 --- a/registry/remote/repository_test.go +++ b/registry/remote/repository_test.go @@ -1272,6 +1272,7 @@ func TestRepository_Predecessors(t *testing.T) { MediaType: ocispec.MediaTypeImageIndex, Manifests: referrers, } + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) if err := json.NewEncoder(w).Encode(result); err != nil { t.Errorf("failed to write response: %v", err) } @@ -1384,6 +1385,7 @@ func TestRepository_Referrers(t *testing.T) { MediaType: ocispec.MediaTypeImageIndex, Manifests: referrers, } + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) if err := json.NewEncoder(w).Encode(result); err != nil { t.Errorf("failed to write response: %v", err) } @@ -1680,6 +1682,58 @@ func TestRepository_Referrers_TagSchemaFallback_NotFound(t *testing.T) { } } +func TestRepository_Referrers_TagSchemaFallback_ContentType(t *testing.T) { + manifest := []byte(`{"layers":[]}`) + manifestDesc := ocispec.Descriptor{ + MediaType: ocispec.MediaTypeImageManifest, + Digest: digest.FromBytes(manifest), + Size: int64(len(manifest)), + } + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + referrersUrl := "/v2/test/referrers/" + manifestDesc.Digest.String() + referrersTag := strings.Replace(manifestDesc.Digest.String(), ":", "-", 1) + tagSchemaUrl := "/v2/test/manifests/" + referrersTag + if r.URL.Path == referrersUrl { + w.Header().Set("Content-Type", "application/json") // not an OCI image index + w.WriteHeader(http.StatusOK) + return + } + if r.Method == http.MethodGet || + r.URL.Path == tagSchemaUrl { + w.WriteHeader(http.StatusNotFound) + return + } + t.Errorf("unexpected access: %s %q", r.Method, r.URL) + w.WriteHeader(http.StatusNotFound) + })) + defer ts.Close() + uri, err := url.Parse(ts.URL) + if err != nil { + t.Fatalf("invalid test http server: %v", err) + } + ctx := context.Background() + + // test auto detect + // tag schema referrers not found, should be no error + repo, err := NewRepository(uri.Host + "/test") + if err != nil { + t.Fatalf("NewRepository() error = %v", err) + } + repo.PlainHTTP = true + if state := repo.loadReferrersState(); state != referrersStateUnknown { + t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateUnknown) + } + if err := repo.Referrers(ctx, manifestDesc, "", func(got []ocispec.Descriptor) error { + return nil + }); err != nil { + t.Errorf("Repository.Referrers() error = %v", err) + } + if state := repo.loadReferrersState(); state != referrersStateUnsupported { + t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateUnsupported) + } +} + func TestRepository_Referrers_BadRequest(t *testing.T) { manifest := []byte(`{"layers":[]}`) manifestDesc := ocispec.Descriptor{ @@ -1944,6 +1998,7 @@ func TestRepository_Referrers_ServerFiltering(t *testing.T) { spec.AnnotationReferrersFiltersApplied: "artifactType", }, } + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) if err := json.NewEncoder(w).Encode(result); err != nil { t.Errorf("failed to write response: %v", err) } @@ -2019,6 +2074,7 @@ func TestRepository_Referrers_ServerFiltering(t *testing.T) { MediaType: ocispec.MediaTypeImageIndex, Manifests: referrers, } + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) // set filter header w.Header().Set("OCI-Filters-Applied", "artifactType") if err := json.NewEncoder(w).Encode(result); err != nil { @@ -2100,6 +2156,7 @@ func TestRepository_Referrers_ServerFiltering(t *testing.T) { spec.AnnotationReferrersFiltersApplied: "artifactType", }, } + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) // set filter header w.Header().Set("OCI-Filters-Applied", "artifactType") if err := json.NewEncoder(w).Encode(result); err != nil { @@ -2241,6 +2298,7 @@ func TestRepository_Referrers_ClientFiltering(t *testing.T) { MediaType: ocispec.MediaTypeImageIndex, Manifests: referrers, } + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) if err := json.NewEncoder(w).Encode(result); err != nil { t.Errorf("failed to write response: %v", err) } @@ -3502,6 +3560,7 @@ func Test_ManifestStore_Push_ReferrersAPIAvailable_NoSubjectHeader(t *testing.T) MediaType: ocispec.MediaTypeImageIndex, Manifests: []ocispec.Descriptor{}, } + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) if err := json.NewEncoder(w).Encode(result); err != nil { t.Errorf("failed to write response: %v", err) } @@ -4503,6 +4562,7 @@ func Test_ManifestStore_Delete_ReferrersAPIAvailable(t *testing.T) { MediaType: ocispec.MediaTypeImageIndex, Manifests: []ocispec.Descriptor{}, } + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) if err := json.NewEncoder(w).Encode(result); err != nil { t.Errorf("failed to write response: %v", err) } @@ -5887,6 +5947,7 @@ func Test_ManifestStore_PushReference_ReferrersAPIAvailable_NoSubjectHeader(t *t MediaType: ocispec.MediaTypeImageIndex, Manifests: []ocispec.Descriptor{}, } + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) if err := json.NewEncoder(w).Encode(result); err != nil { t.Errorf("failed to write response: %v", err) } @@ -7076,129 +7137,171 @@ func Test_generateIndex(t *testing.T) { } func TestRepository_pingReferrers(t *testing.T) { - // referrers available - count := 0 - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - switch { - case r.Method == http.MethodGet && r.URL.Path == "/v2/test/referrers/"+zeroDigest: - count++ - w.WriteHeader(http.StatusOK) - default: - t.Errorf("unexpected access: %s %s", r.Method, r.URL) - w.WriteHeader(http.StatusNotFound) + t.Run("referrers available", func(t *testing.T) { + count := 0 + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch { + case r.Method == http.MethodGet && r.URL.Path == "/v2/test/referrers/"+zeroDigest: + count++ + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) + w.WriteHeader(http.StatusOK) + default: + t.Errorf("unexpected access: %s %s", r.Method, r.URL) + w.WriteHeader(http.StatusNotFound) + } + + })) + defer ts.Close() + uri, err := url.Parse(ts.URL) + if err != nil { + t.Fatalf("invalid test http server: %v", err) } - })) - defer ts.Close() - uri, err := url.Parse(ts.URL) - if err != nil { - t.Fatalf("invalid test http server: %v", err) - } + ctx := context.Background() + repo, err := NewRepository(uri.Host + "/test") + if err != nil { + t.Fatalf("NewRepository() error = %v", err) + } + repo.PlainHTTP = true - ctx := context.Background() - repo, err := NewRepository(uri.Host + "/test") - if err != nil { - t.Fatalf("NewRepository() error = %v", err) - } - repo.PlainHTTP = true + // 1st call + if state := repo.loadReferrersState(); state != referrersStateUnknown { + t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateUnknown) + } + got, err := repo.pingReferrers(ctx) + if err != nil { + t.Errorf("Repository.pingReferrers() error = %v, wantErr %v", err, nil) + } + if got != true { + t.Errorf("Repository.pingReferrers() = %v, want %v", got, true) + } + if state := repo.loadReferrersState(); state != referrersStateSupported { + t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateSupported) + } + if count != 1 { + t.Errorf("count(Repository.pingReferrers()) = %v, want %v", count, 1) + } - // 1st call - if state := repo.loadReferrersState(); state != referrersStateUnknown { - t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateUnknown) - } - got, err := repo.pingReferrers(ctx) - if err != nil { - t.Errorf("Repository.pingReferrers() error = %v, wantErr %v", err, nil) - } - if got != true { - t.Errorf("Repository.pingReferrers() = %v, want %v", got, true) - } - if state := repo.loadReferrersState(); state != referrersStateSupported { - t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateSupported) - } - if count != 1 { - t.Errorf("count(Repository.pingReferrers()) = %v, want %v", count, 1) - } + // 2nd call + if state := repo.loadReferrersState(); state != referrersStateSupported { + t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateSupported) + } + got, err = repo.pingReferrers(ctx) + if err != nil { + t.Errorf("Repository.pingReferrers() error = %v, wantErr %v", err, nil) + } + if got != true { + t.Errorf("Repository.pingReferrers() = %v, want %v", got, true) + } + if state := repo.loadReferrersState(); state != referrersStateSupported { + t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateSupported) + } + if count != 1 { + t.Errorf("count(Repository.pingReferrers()) = %v, want %v", count, 1) + } + }) - // 2nd call - if state := repo.loadReferrersState(); state != referrersStateSupported { - t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateSupported) - } - got, err = repo.pingReferrers(ctx) - if err != nil { - t.Errorf("Repository.pingReferrers() error = %v, wantErr %v", err, nil) - } - if got != true { - t.Errorf("Repository.pingReferrers() = %v, want %v", got, true) - } - if state := repo.loadReferrersState(); state != referrersStateSupported { - t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateSupported) - } - if count != 1 { - t.Errorf("count(Repository.pingReferrers()) = %v, want %v", count, 1) - } + t.Run("referrers unavailable", func(t *testing.T) { + count := 0 + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch { + case r.Method == http.MethodGet && r.URL.Path == "/v2/test/referrers/"+zeroDigest: + count++ + w.WriteHeader(http.StatusNotFound) + default: + t.Errorf("unexpected access: %s %s", r.Method, r.URL) + w.WriteHeader(http.StatusNotFound) + } + + })) + defer ts.Close() + uri, err := url.Parse(ts.URL) + if err != nil { + t.Fatalf("invalid test http server: %v", err) + } - // referrers unavailable - count = 0 - ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - switch { - case r.Method == http.MethodGet && r.URL.Path == "/v2/test/referrers/"+zeroDigest: - count++ - w.WriteHeader(http.StatusNotFound) - default: - t.Errorf("unexpected access: %s %s", r.Method, r.URL) - w.WriteHeader(http.StatusNotFound) + ctx := context.Background() + repo, err := NewRepository(uri.Host + "/test") + if err != nil { + t.Fatalf("NewRepository() error = %v", err) } + repo.PlainHTTP = true - })) - defer ts.Close() - uri, err = url.Parse(ts.URL) - if err != nil { - t.Fatalf("invalid test http server: %v", err) - } + // 1st call + if state := repo.loadReferrersState(); state != referrersStateUnknown { + t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateUnknown) + } + got, err := repo.pingReferrers(ctx) + if err != nil { + t.Errorf("Repository.pingReferrers() error = %v, wantErr %v", err, nil) + } + if got != false { + t.Errorf("Repository.pingReferrers() = %v, want %v", got, false) + } + if state := repo.loadReferrersState(); state != referrersStateUnsupported { + t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateUnsupported) + } + if count != 1 { + t.Errorf("count(Repository.pingReferrers()) = %v, want %v", count, 1) + } - ctx = context.Background() - repo, err = NewRepository(uri.Host + "/test") - if err != nil { - t.Fatalf("NewRepository() error = %v", err) - } - repo.PlainHTTP = true + // 2nd call + if state := repo.loadReferrersState(); state != referrersStateUnsupported { + t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateUnsupported) + } + got, err = repo.pingReferrers(ctx) + if err != nil { + t.Errorf("Repository.pingReferrers() error = %v, wantErr %v", err, nil) + } + if got != false { + t.Errorf("Repository.pingReferrers() = %v, want %v", got, false) + } + if state := repo.loadReferrersState(); state != referrersStateUnsupported { + t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateUnsupported) + } + if count != 1 { + t.Errorf("count(Repository.pingReferrers()) = %v, want %v", count, 1) + } + }) - // 1st call - if state := repo.loadReferrersState(); state != referrersStateUnknown { - t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateUnknown) - } - got, err = repo.pingReferrers(ctx) - if err != nil { - t.Errorf("Repository.pingReferrers() error = %v, wantErr %v", err, nil) - } - if got != false { - t.Errorf("Repository.pingReferrers() = %v, want %v", got, false) - } - if state := repo.loadReferrersState(); state != referrersStateUnsupported { - t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateUnsupported) - } - if count != 1 { - t.Errorf("count(Repository.pingReferrers()) = %v, want %v", count, 1) - } + t.Run("referrers unavailable incorrect content type", func(t *testing.T) { + count := 0 + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch { + case r.Method == http.MethodGet && r.URL.Path == "/v2/test/referrers/"+zeroDigest: + count++ + w.Header().Set("Content-Type", "text/html") // can be anything except an OCI image index + w.WriteHeader(http.StatusOK) + default: + t.Errorf("unexpected access: %s %s", r.Method, r.URL) + w.WriteHeader(http.StatusNotFound) + } - // 2nd call - if state := repo.loadReferrersState(); state != referrersStateUnsupported { - t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateUnsupported) - } - got, err = repo.pingReferrers(ctx) - if err != nil { - t.Errorf("Repository.pingReferrers() error = %v, wantErr %v", err, nil) - } - if got != false { - t.Errorf("Repository.pingReferrers() = %v, want %v", got, false) - } - if state := repo.loadReferrersState(); state != referrersStateUnsupported { - t.Errorf("Repository.loadReferrersState() = %v, want %v", state, referrersStateUnsupported) - } - if count != 1 { - t.Errorf("count(Repository.pingReferrers()) = %v, want %v", count, 1) - } + })) + defer ts.Close() + uri, err := url.Parse(ts.URL) + if err != nil { + t.Fatalf("invalid test http server: %v", err) + } + + ctx := context.Background() + repo, err := NewRepository(uri.Host + "/test") + if err != nil { + t.Fatalf("NewRepository() error = %v", err) + } + repo.PlainHTTP = true + + got, err := repo.pingReferrers(ctx) + if err != nil { + t.Errorf("Repository.pingReferrers() error = %v, wantErr %v", err, nil) + } + if got != false { + t.Errorf("Repository.pingReferrers() = %v, want %v", got, false) + } + if count != 1 { + t.Errorf("count(Repository.pingReferrers()) = %v, want %v", count, 1) + } + }) } func TestRepository_pingReferrers_RepositoryNotFound(t *testing.T) { @@ -7284,6 +7387,7 @@ func TestRepository_pingReferrers_Concurrent(t *testing.T) { switch { case r.Method == http.MethodGet && r.URL.Path == "/v2/test/referrers/"+zeroDigest: atomic.AddInt32(&count, 1) + w.Header().Set("Content-Type", ocispec.MediaTypeImageIndex) w.WriteHeader(http.StatusOK) default: t.Errorf("unexpected access: %s %s", r.Method, r.URL)