...
1
2
3
4
5
6
7 package ctxhttp
8
9 import (
10 "context"
11 "io"
12 "io/ioutil"
13 "net/http"
14 "net/http/httptest"
15 "testing"
16 "time"
17 )
18
19 func TestGo17Context(t *testing.T) {
20 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
21 io.WriteString(w, "ok")
22 }))
23 defer ts.Close()
24 ctx := context.Background()
25 resp, err := Get(ctx, http.DefaultClient, ts.URL)
26 if resp == nil || err != nil {
27 t.Fatalf("error received from client: %v %v", err, resp)
28 }
29 resp.Body.Close()
30 }
31
32 const (
33 requestDuration = 100 * time.Millisecond
34 requestBody = "ok"
35 )
36
37 func okHandler(w http.ResponseWriter, r *http.Request) {
38 time.Sleep(requestDuration)
39 io.WriteString(w, requestBody)
40 }
41
42 func TestNoTimeout(t *testing.T) {
43 ts := httptest.NewServer(http.HandlerFunc(okHandler))
44 defer ts.Close()
45
46 ctx := context.Background()
47 res, err := Get(ctx, nil, ts.URL)
48 if err != nil {
49 t.Fatal(err)
50 }
51 defer res.Body.Close()
52 slurp, err := ioutil.ReadAll(res.Body)
53 if err != nil {
54 t.Fatal(err)
55 }
56 if string(slurp) != requestBody {
57 t.Errorf("body = %q; want %q", slurp, requestBody)
58 }
59 }
60
61 func TestCancelBeforeHeaders(t *testing.T) {
62 ctx, cancel := context.WithCancel(context.Background())
63
64 blockServer := make(chan struct{})
65 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
66 cancel()
67 <-blockServer
68 io.WriteString(w, requestBody)
69 }))
70 defer ts.Close()
71 defer close(blockServer)
72
73 res, err := Get(ctx, nil, ts.URL)
74 if err == nil {
75 res.Body.Close()
76 t.Fatal("Get returned unexpected nil error")
77 }
78 if err != context.Canceled {
79 t.Errorf("err = %v; want %v", err, context.Canceled)
80 }
81 }
82
83 func TestCancelAfterHangingRequest(t *testing.T) {
84 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
85 w.WriteHeader(http.StatusOK)
86 w.(http.Flusher).Flush()
87 <-w.(http.CloseNotifier).CloseNotify()
88 }))
89 defer ts.Close()
90
91 ctx, cancel := context.WithCancel(context.Background())
92 resp, err := Get(ctx, nil, ts.URL)
93 if err != nil {
94 t.Fatalf("unexpected error in Get: %v", err)
95 }
96
97
98
99
100 cancel()
101
102 done := make(chan struct{})
103
104 go func() {
105 b, err := ioutil.ReadAll(resp.Body)
106 if len(b) != 0 || err == nil {
107 t.Errorf(`Read got (%q, %v); want ("", error)`, b, err)
108 }
109 close(done)
110 }()
111
112 select {
113 case <-time.After(1 * time.Second):
114 t.Errorf("Test timed out")
115 case <-done:
116 }
117 }
118
View as plain text