requests_test.go 5.5 KB

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