requests_test.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. package httpc
  2. import (
  3. "context"
  4. "net/http"
  5. "net/http/httptest"
  6. "net/http/httptrace"
  7. "testing"
  8. "github.com/stretchr/testify/assert"
  9. ztrace "github.com/zeromicro/go-zero/core/trace"
  10. "github.com/zeromicro/go-zero/rest/httpx"
  11. "github.com/zeromicro/go-zero/rest/internal/header"
  12. "github.com/zeromicro/go-zero/rest/router"
  13. "go.opentelemetry.io/otel/trace"
  14. )
  15. func TestDoRequest(t *testing.T) {
  16. ztrace.StartAgent(ztrace.Config{
  17. Name: "go-zero-test",
  18. Endpoint: "http://localhost:14268/api/traces",
  19. Batcher: "jaeger",
  20. Sampler: 1.0,
  21. })
  22. defer ztrace.StopAgent()
  23. svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  24. }))
  25. defer svr.Close()
  26. req, err := http.NewRequest(http.MethodGet, svr.URL, nil)
  27. assert.Nil(t, err)
  28. resp, err := DoRequest(req)
  29. assert.Nil(t, err)
  30. assert.Equal(t, http.StatusOK, resp.StatusCode)
  31. spanContext := trace.SpanContextFromContext(resp.Request.Context())
  32. assert.True(t, spanContext.IsValid())
  33. }
  34. func TestDoRequest_NotFound(t *testing.T) {
  35. svr := httptest.NewServer(http.NotFoundHandler())
  36. defer svr.Close()
  37. req, err := http.NewRequest(http.MethodPost, svr.URL, nil)
  38. assert.Nil(t, err)
  39. req.Header.Set(header.ContentType, header.JsonContentType)
  40. resp, err := DoRequest(req)
  41. assert.Nil(t, err)
  42. assert.Equal(t, http.StatusNotFound, resp.StatusCode)
  43. }
  44. func TestDoRequest_Moved(t *testing.T) {
  45. svr := httptest.NewServer(http.RedirectHandler("/foo", http.StatusMovedPermanently))
  46. defer svr.Close()
  47. req, err := http.NewRequest(http.MethodGet, svr.URL, nil)
  48. assert.Nil(t, err)
  49. _, err = DoRequest(req)
  50. // too many redirects
  51. assert.NotNil(t, err)
  52. }
  53. func TestDo(t *testing.T) {
  54. type Data struct {
  55. Key string `path:"key"`
  56. Value int `form:"value"`
  57. Header string `header:"X-Header"`
  58. Body string `json:"body"`
  59. }
  60. rt := router.NewRouter()
  61. err := rt.Handle(http.MethodPost, "/nodes/:key",
  62. http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  63. var req Data
  64. assert.Nil(t, httpx.Parse(r, &req))
  65. }))
  66. assert.Nil(t, err)
  67. svr := httptest.NewServer(http.HandlerFunc(rt.ServeHTTP))
  68. defer svr.Close()
  69. data := Data{
  70. Key: "foo",
  71. Value: 10,
  72. Header: "my-header",
  73. Body: "my body",
  74. }
  75. resp, err := Do(context.Background(), http.MethodPost, svr.URL+"/nodes/:key", data)
  76. assert.Nil(t, err)
  77. assert.Equal(t, http.StatusOK, resp.StatusCode)
  78. }
  79. func TestDo_Ptr(t *testing.T) {
  80. type Data struct {
  81. Key string `path:"key"`
  82. Value int `form:"value"`
  83. Header string `header:"X-Header"`
  84. Body string `json:"body"`
  85. }
  86. rt := router.NewRouter()
  87. err := rt.Handle(http.MethodPost, "/nodes/:key",
  88. http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  89. var req Data
  90. assert.Nil(t, httpx.Parse(r, &req))
  91. assert.Equal(t, "foo", req.Key)
  92. assert.Equal(t, 10, req.Value)
  93. assert.Equal(t, "my-header", req.Header)
  94. assert.Equal(t, "my body", req.Body)
  95. }))
  96. assert.Nil(t, err)
  97. svr := httptest.NewServer(http.HandlerFunc(rt.ServeHTTP))
  98. defer svr.Close()
  99. data := &Data{
  100. Key: "foo",
  101. Value: 10,
  102. Header: "my-header",
  103. Body: "my body",
  104. }
  105. resp, err := Do(context.Background(), http.MethodPost, svr.URL+"/nodes/:key", data)
  106. assert.Nil(t, err)
  107. assert.Equal(t, http.StatusOK, resp.StatusCode)
  108. }
  109. func TestDo_BadRequest(t *testing.T) {
  110. _, err := Do(context.Background(), http.MethodPost, ":/nodes/:key", nil)
  111. assert.NotNil(t, err)
  112. val1 := struct {
  113. Value string `json:"value,options=[a,b]"`
  114. }{
  115. Value: "c",
  116. }
  117. _, err = Do(context.Background(), http.MethodPost, "/nodes/:key", val1)
  118. assert.NotNil(t, err)
  119. val2 := struct {
  120. Value string `path:"val"`
  121. }{
  122. Value: "",
  123. }
  124. _, err = Do(context.Background(), http.MethodPost, "/nodes/:key", val2)
  125. assert.NotNil(t, err)
  126. val3 := struct {
  127. Value string `path:"key"`
  128. Body string `json:"body"`
  129. }{
  130. Value: "foo",
  131. }
  132. _, err = Do(context.Background(), http.MethodGet, "/nodes/:key", val3)
  133. assert.NotNil(t, err)
  134. _, err = Do(context.Background(), "\n", "rtmp://nodes", nil)
  135. assert.NotNil(t, err)
  136. val4 := struct {
  137. Value string `path:"val"`
  138. }{
  139. Value: "",
  140. }
  141. _, err = Do(context.Background(), http.MethodPost, "/nodes/:val", val4)
  142. assert.NotNil(t, err)
  143. val5 := struct {
  144. Value string `path:"val"`
  145. Another int `path:"foo"`
  146. }{
  147. Value: "1",
  148. Another: 2,
  149. }
  150. _, err = Do(context.Background(), http.MethodPost, "/nodes/:val", val5)
  151. assert.NotNil(t, err)
  152. }
  153. func TestDo_Json(t *testing.T) {
  154. type Data struct {
  155. Key string `path:"key"`
  156. Value int `form:"value"`
  157. Header string `header:"X-Header"`
  158. Body chan int `json:"body"`
  159. }
  160. rt := router.NewRouter()
  161. err := rt.Handle(http.MethodPost, "/nodes/:key",
  162. http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  163. var req Data
  164. assert.Nil(t, httpx.Parse(r, &req))
  165. }))
  166. assert.Nil(t, err)
  167. svr := httptest.NewServer(http.HandlerFunc(rt.ServeHTTP))
  168. defer svr.Close()
  169. data := Data{
  170. Key: "foo",
  171. Value: 10,
  172. Header: "my-header",
  173. Body: make(chan int),
  174. }
  175. _, err = Do(context.Background(), http.MethodPost, svr.URL+"/nodes/:key", data)
  176. assert.NotNil(t, err)
  177. }
  178. func TestDo_WithClientHttpTrace(t *testing.T) {
  179. svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
  180. defer svr.Close()
  181. _, err := Do(httptrace.WithClientTrace(context.Background(),
  182. &httptrace.ClientTrace{
  183. DNSStart: func(info httptrace.DNSStartInfo) {
  184. assert.Equal(t, "localhost", info.Host)
  185. },
  186. }), http.MethodGet, svr.URL, nil)
  187. assert.Nil(t, err)
  188. }