package api import ( "context" "errors" "io" "net/http" "net/http/httptest" "syscall" "testing" ) func TestExpectedClientDisconnect(t *testing.T) { req := httptest.NewRequest(http.MethodGet, "/v1/images/1/primary", nil) for _, err := range []error{ context.Canceled, syscall.EPIPE, syscall.ECONNRESET, errors.New("write tcp: broken pipe"), errors.New("client disconnected"), } { if !expectedClientDisconnect(req, err) { t.Errorf("%q should be an expected client disconnect", err) } } if expectedClientDisconnect(req, io.ErrUnexpectedEOF) { t.Fatal("an upstream truncated image must remain a real warning") } } func TestExpectedClientDisconnectUsesRequestContext(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) cancel() req := httptest.NewRequest(http.MethodGet, "/v1/images/1/primary", nil).WithContext(ctx) if !expectedClientDisconnect(req, errors.New("opaque response writer error")) { t.Fatal("a cancelled request should be treated as viewer cancellation") } } func TestTaggedImageConditionalRequestSkipsUpstream(t *testing.T) { req := httptest.NewRequest(http.MethodGet, "/v1/images/1/primary?tag=abc123", nil) req.Header.Set("If-None-Match", `"abc123"`) rec := httptest.NewRecorder() if !writeNotModifiedForTag(rec, req, "abc123") { t.Fatal("matching image tag should short-circuit") } if rec.Code != http.StatusNotModified { t.Fatalf("status = %d, want 304", rec.Code) } if got := rec.Header().Get("ETag"); got != `"abc123"` { t.Fatalf("etag = %q", got) } }