master
go 63 lines 1.92 KB
Raw
1 package shutdown
2
3 import (
4 "context"
5 "errors"
6 "testing"
7 "testing/synctest"
8 "time"
9 )
10
11 const (
12 // testFinishDeadline is the ctx deadline for the happy-path tests:
13 // long enough that the close callback returns first.
14 testFinishDeadline = time.Second
15 // testTimeoutDeadline is the ctx deadline for the timeout test. Any
16 // positive value works because the test runs under synctest's fake
17 // clock; the choice only affects the exact-elapsed assertion below.
18 testTimeoutDeadline = 50 * time.Millisecond
19 )
20
21 func TestCloseWithCtx_finishesBeforeDeadline(t *testing.T) {
22 t.Parallel()
23 ctx, cancel := context.WithTimeout(context.Background(), testFinishDeadline)
24 defer cancel()
25 if err := CloseWithCtx(ctx, "fast", func() error { return nil }); err != nil {
26 t.Fatal(err)
27 }
28 }
29
30 func TestCloseWithCtx_propagatesCloseError(t *testing.T) {
31 t.Parallel()
32 ctx, cancel := context.WithTimeout(context.Background(), testFinishDeadline)
33 defer cancel()
34 want := errors.New("close failed")
35 err := CloseWithCtx(ctx, "bad", func() error { return want })
36 if !errors.Is(err, want) {
37 t.Fatalf("want %v, got %v", want, err)
38 }
39 }
40
41 func TestCloseWithCtx_timesOut(t *testing.T) {
42 synctest.Test(t, func(t *testing.T) {
43 ctx, cancel := context.WithTimeout(context.Background(), testTimeoutDeadline)
44 defer cancel()
45 // release lets the simulated close exit after we've asserted on
46 // CloseWithCtx. Without it, synctest panics with "blocked
47 // goroutines remain" because production-side CloseWithCtx
48 // intentionally leaks the goroutine when the deadline fires.
49 release := make(chan struct{})
50 start := time.Now()
51 err := CloseWithCtx(ctx, "slow", func() error {
52 <-release
53 return nil
54 })
55 if elapsed := time.Since(start); elapsed != testTimeoutDeadline {
56 t.Fatalf("want elapsed == %s, got %s", testTimeoutDeadline, elapsed)
57 }
58 if !errors.Is(err, context.DeadlineExceeded) {
59 t.Fatalf("want DeadlineExceeded, got %v", err)
60 }
61 close(release)
62 })
63 }