Test that a shared miss keeps its deadline and reports panics (closes #65)
A request with a deadline whose fetch waits on its context, as the fetcher does while it waits for a free connection to the host, must return by that deadline. A panic while a variant is being made must be reported through the Sentry hub on the request's context, where the Sentry middleware puts one when sentry_dsn is set. The panic test fails on next, where the panic leaves Get. Model: opus-5-5
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/getsentry/sentry-go"
|
||||||
"sneak.berlin/go/pixa/internal/httpfetcher"
|
"sneak.berlin/go/pixa/internal/httpfetcher"
|
||||||
"sneak.berlin/go/pixa/internal/magic"
|
"sneak.berlin/go/pixa/internal/magic"
|
||||||
)
|
)
|
||||||
@@ -408,6 +409,32 @@ func TestService_Get_EndedRequestFetchesNothing(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestService_Get_ReturnsByItsDeadline gives a request a deadline and holds
|
||||||
|
// its fetch until the fetch's context ends, as the fetcher does while it waits
|
||||||
|
// for a free connection to the host. The request must return by its deadline
|
||||||
|
// with the deadline's error.
|
||||||
|
func TestService_Get_ReturnsByItsDeadline(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
svc, fixtures, _ := setupHeldFetchService(t)
|
||||||
|
|
||||||
|
const timeout = 200 * time.Millisecond
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(t.Context(), timeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
results := startGet(ctx, svc, photoVariant(fixtures, 85, FitCover))
|
||||||
|
|
||||||
|
select {
|
||||||
|
case got := <-results:
|
||||||
|
if !errors.Is(got.err, context.DeadlineExceeded) {
|
||||||
|
t.Errorf("Get() error = %v, want %v", got.err, context.DeadlineExceeded)
|
||||||
|
}
|
||||||
|
case <-time.After(timeout + time.Second):
|
||||||
|
t.Fatal("request did not return by its deadline")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// panickingFetcher panics on every fetch.
|
// panickingFetcher panics on every fetch.
|
||||||
type panickingFetcher struct{}
|
type panickingFetcher struct{}
|
||||||
|
|
||||||
@@ -442,3 +469,41 @@ func TestService_Get_PanicBecomesAnError(t *testing.T) {
|
|||||||
t.Errorf("Get() error = %v, want one naming the panic", err)
|
t.Errorf("Get() error = %v, want one naming the panic", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestService_Get_PanicIsReportedToSentry checks that a panic while a variant
|
||||||
|
// is being made is reported through the Sentry hub on the request's context,
|
||||||
|
// where the Sentry middleware puts one when sentry_dsn is set.
|
||||||
|
func TestService_Get_PanicIsReportedToSentry(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
svc, fixtures := SetupTestService(t)
|
||||||
|
svc.fetcher = panickingFetcher{}
|
||||||
|
|
||||||
|
transport := &sentry.MockTransport{}
|
||||||
|
|
||||||
|
client, err := sentry.NewClient(sentry.ClientOptions{
|
||||||
|
Dsn: "https://abc123@sentry.example.com/42",
|
||||||
|
Transport: transport,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := sentry.SetHubOnContext(t.Context(),
|
||||||
|
sentry.NewHub(client, sentry.NewScope()))
|
||||||
|
|
||||||
|
func() {
|
||||||
|
defer func() {
|
||||||
|
if recovered := recover(); recovered != nil {
|
||||||
|
t.Fatalf("Get() panicked: %v", recovered)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, _ = svc.Get(ctx, photoVariant(fixtures, 85, FitCover))
|
||||||
|
}()
|
||||||
|
|
||||||
|
events := transport.Events()
|
||||||
|
if len(events) != 1 || events[0].Message != "upstream fetcher panicked" {
|
||||||
|
t.Errorf("Sentry events = %+v, want one for the panic", events)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user