1 package integration_test
2
3 import (
4 "context"
5 "fmt"
6 "io/ioutil"
7 "net/http"
8 "strings"
9 "testing"
10 "time"
11
12 "github.com/golang/protobuf/jsonpb"
13 "github.com/grpc-ecosystem/grpc-gateway/runtime"
14 spb "google.golang.org/genproto/googleapis/rpc/status"
15 "google.golang.org/grpc/codes"
16 )
17
18 func runServer(ctx context.Context, t *testing.T, port uint16) {
19 opt := runtime.WithProtoErrorHandler(runtime.DefaultHTTPProtoErrorHandler)
20 if err := runGateway(ctx, fmt.Sprintf(":%d", port), opt); err != nil {
21 t.Errorf("runGateway() failed with %v; want success", err)
22 }
23 }
24
25 func TestWithProtoErrorHandler(t *testing.T) {
26 if testing.Short() {
27 t.Skip()
28 return
29 }
30
31 ctx := context.Background()
32 ctx, cancel := context.WithCancel(ctx)
33 defer cancel()
34
35 const port = 8082
36 go runServer(ctx, t, port)
37 if err := waitForGateway(ctx, 8082); err != nil {
38 t.Errorf("waitForGateway(ctx, 8082) failed with %v; want success", err)
39 }
40 testEcho(t, port, "application/json")
41 testEchoBody(t, port)
42 }
43
44 func TestABEWithProtoErrorHandler(t *testing.T) {
45 if testing.Short() {
46 t.Skip()
47 return
48 }
49
50 ctx := context.Background()
51 ctx, cancel := context.WithCancel(ctx)
52 defer cancel()
53
54 const port = 8083
55 go runServer(ctx, t, port)
56 if err := waitForGateway(ctx, 8083); err != nil {
57 t.Errorf("waitForGateway(ctx, 8083) failed with %v; want success", err)
58 }
59
60 testABECreate(t, port)
61 testABECreateBody(t, port)
62 testABEBulkCreate(t, port)
63 testABELookup(t, port)
64 testABELookupNotFoundWithProtoError(t, port)
65 testABEList(t, port)
66 testABEBulkEcho(t, port)
67 testABEBulkEchoZeroLength(t, port)
68 testAdditionalBindings(t, port)
69 }
70
71 func testABELookupNotFoundWithProtoError(t *testing.T, port uint16) {
72 url := fmt.Sprintf("http://localhost:%d/v1/example/a_bit_of_everything", port)
73 uuid := "not_exist"
74 url = fmt.Sprintf("%s/%s", url, uuid)
75 resp, err := http.Get(url)
76 if err != nil {
77 t.Errorf("http.Get(%q) failed with %v; want success", url, err)
78 return
79 }
80 defer resp.Body.Close()
81
82 buf, err := ioutil.ReadAll(resp.Body)
83 if err != nil {
84 t.Errorf("ioutil.ReadAll(resp.Body) failed with %v; want success", err)
85 return
86 }
87
88 if got, want := resp.StatusCode, http.StatusNotFound; got != want {
89 t.Errorf("resp.StatusCode = %d; want %d", got, want)
90 t.Logf("%s", buf)
91 return
92 }
93
94 var msg spb.Status
95 if err := jsonpb.UnmarshalString(string(buf), &msg); err != nil {
96 t.Errorf("jsonpb.UnmarshalString(%s, &msg) failed with %v; want success", buf, err)
97 return
98 }
99
100 if got, want := msg.Code, int32(codes.NotFound); got != want {
101 t.Errorf("msg.Code = %d; want %d", got, want)
102 return
103 }
104
105 if got, want := msg.Message, "not found"; got != want {
106 t.Errorf("msg.Message = %s; want %s", got, want)
107 return
108 }
109
110 if got, want := resp.Header.Get("Grpc-Metadata-Uuid"), uuid; got != want {
111 t.Errorf("Grpc-Metadata-Uuid was %s, wanted %s", got, want)
112 }
113 if got, want := resp.Trailer.Get("Grpc-Trailer-Foo"), "foo2"; got != want {
114 t.Errorf("Grpc-Trailer-Foo was %q, wanted %q", got, want)
115 }
116 if got, want := resp.Trailer.Get("Grpc-Trailer-Bar"), "bar2"; got != want {
117 t.Errorf("Grpc-Trailer-Bar was %q, wanted %q", got, want)
118 }
119 }
120
121 func TestUnknownPathWithProtoError(t *testing.T) {
122 if testing.Short() {
123 t.Skip()
124 return
125 }
126
127 ctx := context.Background()
128 ctx, cancel := context.WithCancel(ctx)
129 defer cancel()
130
131 const port = 8084
132 go runServer(ctx, t, port)
133 if err := waitForGateway(ctx, 8084); err != nil {
134 t.Errorf("waitForGateway(ctx, 8084) failed with %v; want success", err)
135 }
136
137 url := fmt.Sprintf("http://localhost:%d", port)
138 resp, err := http.Post(url, "application/json", strings.NewReader("{}"))
139 if err != nil {
140 t.Errorf("http.Post(%q) failed with %v; want success", url, err)
141 return
142 }
143 defer resp.Body.Close()
144 buf, err := ioutil.ReadAll(resp.Body)
145 if err != nil {
146 t.Errorf("ioutil.ReadAll(resp.Body) failed with %v; want success", err)
147 return
148 }
149
150 if got, want := resp.StatusCode, http.StatusNotImplemented; got != want {
151 t.Errorf("resp.StatusCode = %d; want %d", got, want)
152 t.Logf("%s", buf)
153 }
154
155 var msg spb.Status
156 if err := jsonpb.UnmarshalString(string(buf), &msg); err != nil {
157 t.Errorf("jsonpb.UnmarshalString(%s, &msg) failed with %v; want success", buf, err)
158 return
159 }
160
161 if got, want := msg.Code, int32(codes.Unimplemented); got != want {
162 t.Errorf("msg.Code = %d; want %d", got, want)
163 return
164 }
165
166 if msg.Message == "" {
167 t.Errorf("msg.Message should not be empty")
168 return
169 }
170 }
171
172 func TestMethodNotAllowedWithProtoError(t *testing.T) {
173 if testing.Short() {
174 t.Skip()
175 return
176 }
177
178 ctx := context.Background()
179 ctx, cancel := context.WithCancel(ctx)
180 defer cancel()
181
182 const port = 8085
183 go runServer(ctx, t, port)
184
185
186
187 time.Sleep(100 * time.Millisecond)
188
189 url := fmt.Sprintf("http://localhost:%d/v1/example/echo/myid", port)
190 resp, err := http.Get(url)
191 if err != nil {
192 t.Errorf("http.Post(%q) failed with %v; want success", url, err)
193 return
194 }
195 defer resp.Body.Close()
196 buf, err := ioutil.ReadAll(resp.Body)
197 if err != nil {
198 t.Errorf("ioutil.ReadAll(resp.Body) failed with %v; want success", err)
199 return
200 }
201
202 if got, want := resp.StatusCode, http.StatusNotImplemented; got != want {
203 t.Errorf("resp.StatusCode = %d; want %d", got, want)
204 t.Logf("%s", buf)
205 }
206
207 var msg spb.Status
208 if err := jsonpb.UnmarshalString(string(buf), &msg); err != nil {
209 t.Errorf("jsonpb.UnmarshalString(%s, &msg) failed with %v; want success", buf, err)
210 return
211 }
212
213 if got, want := msg.Code, int32(codes.Unimplemented); got != want {
214 t.Errorf("msg.Code = %d; want %d", got, want)
215 return
216 }
217
218 if msg.Message == "" {
219 t.Errorf("msg.Message should not be empty")
220 return
221 }
222 }
223
View as plain text