cuelabs.dev/go/oci/ociregistry@v0.0.0-20240906074133-82eb438dd565/ociclient/error_test.go (about) 1 package ociclient 2 3 import ( 4 "context" 5 "errors" 6 "net/http" 7 "net/http/httptest" 8 "net/url" 9 "strings" 10 "testing" 11 12 "cuelabs.dev/go/oci/ociregistry" 13 "cuelabs.dev/go/oci/ociregistry/ociserver" 14 "github.com/go-quicktest/qt" 15 "github.com/opencontainers/go-digest" 16 ) 17 18 func TestErrorStuttering(t *testing.T) { 19 // This checks that the stuttering observed in issue #31 20 // isn't an issue when ociserver wraps ociclient. 21 srv := httptest.NewServer(ociserver.New(&ociregistry.Funcs{ 22 NewError: func(ctx context.Context, methodName, repo string) error { 23 return ociregistry.ErrManifestUnknown 24 }, 25 }, nil)) 26 defer srv.Close() 27 28 srvURL, _ := url.Parse(srv.URL) 29 r, err := New(srvURL.Host, &Options{ 30 Insecure: true, 31 }) 32 qt.Assert(t, qt.IsNil(err)) 33 _, err = r.GetTag(context.Background(), "foo", "sometag") 34 qt.Check(t, qt.ErrorIs(err, ociregistry.ErrManifestUnknown)) 35 qt.Check(t, qt.ErrorMatches(err, `404 Not Found: manifest unknown: manifest unknown to registry`)) 36 37 // ResolveTag uses HEAD rather than GET, so here we're testing 38 // the path where a response with no body gets turned back into 39 // something vaguely resembling the original error, which is why 40 // the code and message have changed. 41 _, err = r.ResolveTag(context.Background(), "foo", "sometag") 42 qt.Check(t, qt.ErrorIs(err, ociregistry.ErrNameUnknown)) 43 qt.Check(t, qt.ErrorMatches(err, `404 Not Found: name unknown: repository name not known to registry`)) 44 } 45 46 func TestNonJSONErrorResponse(t *testing.T) { 47 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 48 w.WriteHeader(http.StatusTeapot) 49 w.Write([]byte("some body")) 50 })) 51 defer srv.Close() 52 53 srvURL, _ := url.Parse(srv.URL) 54 r, err := New(srvURL.Host, &Options{ 55 Insecure: true, 56 }) 57 qt.Assert(t, qt.IsNil(err)) 58 assertStatusCode := func(f func(ctx context.Context, r ociregistry.Interface) error) { 59 err := f(context.Background(), r) 60 var herr ociregistry.HTTPError 61 ok := errors.As(err, &herr) 62 qt.Assert(t, qt.IsTrue(ok)) 63 qt.Assert(t, qt.Equals(herr.StatusCode(), http.StatusTeapot)) 64 } 65 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 66 rd, err := r.GetBlob(ctx, "foo/read", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 67 if rd != nil { 68 rd.Close() 69 } 70 return err 71 }) 72 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 73 rd, err := r.GetBlobRange(ctx, "foo/read", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 100, 200) 74 if rd != nil { 75 rd.Close() 76 } 77 return err 78 }) 79 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 80 rd, err := r.GetManifest(ctx, "foo/read", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 81 if rd != nil { 82 rd.Close() 83 } 84 return err 85 }) 86 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 87 rd, err := r.GetTag(ctx, "foo/read", "sometag") 88 if rd != nil { 89 rd.Close() 90 } 91 return err 92 }) 93 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 94 _, err := r.ResolveBlob(ctx, "foo/read", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 95 return err 96 }) 97 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 98 _, err := r.ResolveManifest(ctx, "foo/read", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 99 return err 100 }) 101 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 102 _, err := r.ResolveTag(ctx, "foo/read", "sometag") 103 return err 104 }) 105 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 106 _, err := r.PushBlob(ctx, "foo/write", ociregistry.Descriptor{ 107 MediaType: "application/json", 108 Digest: "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 109 Size: 3, 110 }, strings.NewReader("foo")) 111 return err 112 }) 113 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 114 w, err := r.PushBlobChunked(ctx, "foo/write", 0) 115 if err != nil { 116 return err 117 } 118 w.Close() 119 return nil 120 }) 121 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 122 w, err := r.PushBlobChunkedResume(ctx, "foo/write", "/someid", 3, 0) 123 if err != nil { 124 return err 125 } 126 data := []byte("some data") 127 if _, err := w.Write(data); err != nil { 128 return err 129 } 130 _, err = w.Commit(digest.FromBytes(data)) 131 return err 132 }) 133 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 134 _, err := r.MountBlob(ctx, "foo/read", "foo/write", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 135 return err 136 }) 137 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 138 _, err := r.PushManifest(ctx, "foo/write", "sometag", []byte("something"), "application/json") 139 return err 140 }) 141 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 142 return r.DeleteBlob(ctx, "foo/write", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 143 }) 144 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 145 return r.DeleteManifest(ctx, "foo/write", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 146 }) 147 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 148 return r.DeleteTag(ctx, "foo/write", "sometag") 149 }) 150 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 151 _, err := ociregistry.All(r.Repositories(ctx, "")) 152 return err 153 }) 154 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 155 _, err := ociregistry.All(r.Tags(ctx, "foo/read", "")) 156 return err 157 }) 158 assertStatusCode(func(ctx context.Context, r ociregistry.Interface) error { 159 _, err := ociregistry.All(r.Referrers(ctx, "foo/read", "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "")) 160 return err 161 }) 162 }