package oci import ( "encoding/json" "net/http" "net/http/httptest" "testing" ) func TestBlobGet(t *testing.T) { fdb := newFakeDB() fdb.addRepo("myrepo", 1) fdb.addBlob(1, "sha256:layerdigest") blobs := newFakeBlobs() blobs.data["sha256:layerdigest"] = []byte("layer-content-bytes") h := NewHandler(fdb, blobs, allowAll(), nil) router := testRouter(h) req := authedRequest("GET", "/v2/myrepo/blobs/sha256:layerdigest", nil) rr := httptest.NewRecorder() router.ServeHTTP(rr, req) if rr.Code != http.StatusOK { t.Fatalf("status: got %d, want %d", rr.Code, http.StatusOK) } if ct := rr.Header().Get("Content-Type"); ct != "application/octet-stream" { t.Fatalf("Content-Type: got %q", ct) } if dcd := rr.Header().Get("Docker-Content-Digest"); dcd != "sha256:layerdigest" { t.Fatalf("Docker-Content-Digest: got %q", dcd) } if cl := rr.Header().Get("Content-Length"); cl != "19" { t.Fatalf("Content-Length: got %q, want %q", cl, "19") } if rr.Body.String() != "layer-content-bytes" { t.Fatalf("body: got %q", rr.Body.String()) } } func TestBlobHead(t *testing.T) { fdb := newFakeDB() fdb.addRepo("myrepo", 1) fdb.addBlob(1, "sha256:layerdigest") blobs := newFakeBlobs() blobs.data["sha256:layerdigest"] = []byte("layer-content-bytes") h := NewHandler(fdb, blobs, allowAll(), nil) router := testRouter(h) req := authedRequest("HEAD", "/v2/myrepo/blobs/sha256:layerdigest", nil) rr := httptest.NewRecorder() router.ServeHTTP(rr, req) if rr.Code != http.StatusOK { t.Fatalf("status: got %d, want %d", rr.Code, http.StatusOK) } if ct := rr.Header().Get("Content-Type"); ct != "application/octet-stream" { t.Fatalf("Content-Type: got %q", ct) } if dcd := rr.Header().Get("Docker-Content-Digest"); dcd != "sha256:layerdigest" { t.Fatalf("Docker-Content-Digest: got %q", dcd) } if cl := rr.Header().Get("Content-Length"); cl != "19" { t.Fatalf("Content-Length: got %q, want %q", cl, "19") } if rr.Body.Len() != 0 { t.Fatalf("HEAD body should be empty, got %d bytes", rr.Body.Len()) } } func TestBlobGetNotInRepo(t *testing.T) { fdb := newFakeDB() fdb.addRepo("myrepo", 1) // Blob NOT added to the repo. blobs := newFakeBlobs() blobs.data["sha256:orphan"] = []byte("data") h := NewHandler(fdb, blobs, allowAll(), nil) router := testRouter(h) req := authedRequest("GET", "/v2/myrepo/blobs/sha256:orphan", nil) rr := httptest.NewRecorder() router.ServeHTTP(rr, req) if rr.Code != http.StatusNotFound { t.Fatalf("status: got %d, want %d", rr.Code, http.StatusNotFound) } var body ociErrorResponse if err := json.NewDecoder(rr.Body).Decode(&body); err != nil { t.Fatalf("decode error body: %v", err) } if len(body.Errors) != 1 || body.Errors[0].Code != "BLOB_UNKNOWN" { t.Fatalf("error code: got %+v, want BLOB_UNKNOWN", body.Errors) } } func TestBlobGetRepoNotFound(t *testing.T) { fdb := newFakeDB() // No repos. h := NewHandler(fdb, newFakeBlobs(), allowAll(), nil) router := testRouter(h) req := authedRequest("GET", "/v2/nosuchrepo/blobs/sha256:abc", nil) rr := httptest.NewRecorder() router.ServeHTTP(rr, req) if rr.Code != http.StatusNotFound { t.Fatalf("status: got %d, want %d", rr.Code, http.StatusNotFound) } var body ociErrorResponse if err := json.NewDecoder(rr.Body).Decode(&body); err != nil { t.Fatalf("decode error body: %v", err) } if len(body.Errors) != 1 || body.Errors[0].Code != "NAME_UNKNOWN" { t.Fatalf("error code: got %+v, want NAME_UNKNOWN", body.Errors) } } func TestBlobGetMultiSegmentRepo(t *testing.T) { fdb := newFakeDB() fdb.addRepo("org/team/app", 1) fdb.addBlob(1, "sha256:layerdigest") blobs := newFakeBlobs() blobs.data["sha256:layerdigest"] = []byte("data") h := NewHandler(fdb, blobs, allowAll(), nil) router := testRouter(h) req := authedRequest("GET", "/v2/org/team/app/blobs/sha256:layerdigest", nil) rr := httptest.NewRecorder() router.ServeHTTP(rr, req) if rr.Code != http.StatusOK { t.Fatalf("status: got %d, want %d", rr.Code, http.StatusOK) } }