client_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. package blademaster
  2. import (
  3. "context"
  4. "net/http"
  5. "net/url"
  6. "strconv"
  7. "testing"
  8. "time"
  9. "go-common/library/ecode"
  10. "go-common/library/net/http/blademaster/tests"
  11. "go-common/library/net/netutil/breaker"
  12. xtime "go-common/library/time"
  13. )
  14. func TestClient(t *testing.T) {
  15. c := &ServerConfig{
  16. Addr: "localhost:8081",
  17. Timeout: xtime.Duration(time.Second),
  18. ReadTimeout: xtime.Duration(time.Second),
  19. WriteTimeout: xtime.Duration(time.Second),
  20. }
  21. engine := Default()
  22. engine.GET("/mytest", func(ctx *Context) {
  23. time.Sleep(time.Millisecond * 500)
  24. ctx.JSON("", nil)
  25. })
  26. engine.GET("/mytest1", func(ctx *Context) {
  27. time.Sleep(time.Millisecond * 500)
  28. ctx.JSON("", nil)
  29. })
  30. engine.SetConfig(c)
  31. engine.Start()
  32. client := NewClient(
  33. &ClientConfig{
  34. App: &App{
  35. Key: "53e2fa226f5ad348",
  36. Secret: "3cf6bd1b0ff671021da5f424fea4b04a",
  37. },
  38. Dial: xtime.Duration(time.Second),
  39. Timeout: xtime.Duration(time.Second),
  40. KeepAlive: xtime.Duration(time.Second),
  41. Breaker: &breaker.Config{
  42. Window: 10 * xtime.Duration(time.Second),
  43. Sleep: 50 * xtime.Duration(time.Millisecond),
  44. Bucket: 10,
  45. Ratio: 0.5,
  46. Request: 100,
  47. },
  48. })
  49. var res struct {
  50. Code int `json:"code"`
  51. }
  52. // test Get
  53. if err := client.Get(context.Background(), "http://api.bilibili.com/x/server/now", "", nil, &res); err != nil {
  54. t.Errorf("HTTPClient: expected no error but got %v", err)
  55. }
  56. if res.Code != 0 {
  57. t.Errorf("HTTPClient: expected code=0 but got %d", res.Code)
  58. }
  59. // test Post
  60. if err := client.Post(context.Background(), "http://api.bilibili.com/x/server/now", "", nil, &res); err != nil {
  61. t.Errorf("HTTPClient: expected no error but got %v", err)
  62. }
  63. if res.Code != -405 {
  64. t.Errorf("HTTPClient: expected code=-405 but got %d", res.Code)
  65. }
  66. // test DialTimeout 172.168.1.1 can't connect.
  67. client.SetConfig(&ClientConfig{Dial: xtime.Duration(time.Second * 5)})
  68. if err := client.Post(context.Background(), "http://172.168.1.1/x/server/now", "", nil, &res); err == nil {
  69. t.Errorf("HTTPClient: expected error but got %v", err)
  70. }
  71. // test server and timeout.
  72. client.SetConfig(&ClientConfig{KeepAlive: xtime.Duration(time.Second * 20), Timeout: xtime.Duration(time.Millisecond * 400)})
  73. if err := client.Get(context.Background(), "http://localhost:8081/mytest", "", nil, &res); err == nil {
  74. t.Errorf("HTTPClient: expected error timeout for request")
  75. }
  76. client.SetConfig(&ClientConfig{Timeout: xtime.Duration(time.Second),
  77. URL: map[string]*ClientConfig{"http://localhost:8081/mytest1": {Timeout: xtime.Duration(time.Millisecond * 300)}}})
  78. if err := client.Get(context.Background(), "http://localhost:8081/mytest", "", nil, &res); err != nil {
  79. t.Errorf("HTTPClient: expected no error but got %v", err)
  80. }
  81. if err := client.Get(context.Background(), "http://localhost:8081/mytest1", "", nil, &res); err == nil {
  82. t.Errorf("HTTPClient: expected error timeout for path")
  83. }
  84. client.SetConfig(&ClientConfig{
  85. Host: map[string]*ClientConfig{"api.bilibili.com": {Timeout: xtime.Duration(time.Millisecond * 300)}},
  86. })
  87. if err := client.Get(context.Background(), "http://api.bilibili.com/x/server/now", "", nil, &res); err != nil {
  88. t.Errorf("HTTPClient: expected no error but got %v", err)
  89. }
  90. client.SetConfig(&ClientConfig{
  91. Host: map[string]*ClientConfig{"api.bilibili.com": {Timeout: xtime.Duration(time.Millisecond * 1)}},
  92. })
  93. if err := client.Get(context.Background(), "http://api.bilibili.com/x/server/now", "", nil, &res); err == nil {
  94. t.Errorf("HTTPClient: expected error timeout but got %v", err)
  95. }
  96. client.SetConfig(&ClientConfig{KeepAlive: xtime.Duration(time.Second * 70)})
  97. }
  98. func TestDo(t *testing.T) {
  99. var (
  100. aid = 5463320
  101. uri = "http://api.bilibili.com/x/server/now"
  102. req *http.Request
  103. client *Client
  104. err error
  105. )
  106. client = NewClient(
  107. &ClientConfig{
  108. App: &App{
  109. Key: "53e2fa226f5ad348",
  110. Secret: "3cf6bd1b0ff671021da5f424fea4b04a",
  111. },
  112. Dial: xtime.Duration(time.Second),
  113. Timeout: xtime.Duration(time.Second),
  114. KeepAlive: xtime.Duration(time.Second),
  115. Breaker: &breaker.Config{
  116. Window: 10 * xtime.Duration(time.Second),
  117. Sleep: 50 * xtime.Duration(time.Millisecond),
  118. Bucket: 10,
  119. Ratio: 0.5,
  120. Request: 100,
  121. },
  122. })
  123. params := url.Values{}
  124. params.Set("aid", strconv.Itoa(aid))
  125. if req, err = client.NewRequest("GET", uri, "", params); err != nil {
  126. t.Errorf("client.NewRequest: get error(%v)", err)
  127. }
  128. var res struct {
  129. Code int `json:"code"`
  130. }
  131. if err = client.Do(context.TODO(), req, &res); err != nil {
  132. t.Errorf("Do: client.Do get error(%v) url: %s", err, realURL(req))
  133. }
  134. }
  135. func BenchmarkDo(b *testing.B) {
  136. once.Do(startServer)
  137. cf := &ClientConfig{
  138. App: &App{
  139. Key: "53e2fa226f5ad348",
  140. Secret: "3cf6bd1b0ff671021da5f424fea4b04a",
  141. },
  142. Dial: xtime.Duration(time.Second),
  143. Timeout: xtime.Duration(time.Second),
  144. KeepAlive: xtime.Duration(time.Second),
  145. Breaker: &breaker.Config{
  146. Window: 1 * xtime.Duration(time.Second),
  147. Sleep: 5 * xtime.Duration(time.Millisecond),
  148. Bucket: 1,
  149. Ratio: 0.5,
  150. Request: 10,
  151. },
  152. URL: map[string]*ClientConfig{
  153. "http://api.bilibili.com/x/server/now": {Timeout: xtime.Duration(time.Second)},
  154. "http://api.bilibili.com/x/server/nowx": {Timeout: xtime.Duration(time.Second)},
  155. },
  156. }
  157. client := NewClient(cf)
  158. uri := "http://api.bilibili.com/x/server/now"
  159. b.ResetTimer()
  160. b.RunParallel(func(pb *testing.PB) {
  161. for pb.Next() {
  162. // client.SetConfig(cf)
  163. req, err := client.NewRequest("GET", uri, "", nil)
  164. if err != nil {
  165. b.Errorf("newRequest: get error(%v)", err)
  166. continue
  167. }
  168. var res struct {
  169. Code int `json:"code"`
  170. }
  171. if err = client.Do(context.TODO(), req, &res); err != nil {
  172. b.Errorf("Do: client.Do get error(%v) url: %s", err, realURL(req))
  173. }
  174. }
  175. })
  176. uri = "http://api.bilibili.com/x/server/nowx" // NOTE: for breaker
  177. b.ResetTimer()
  178. b.RunParallel(func(pb *testing.PB) {
  179. for pb.Next() {
  180. // client.SetConfig(cf)
  181. req, err := client.NewRequest("GET", uri, "", nil)
  182. if err != nil {
  183. b.Errorf("newRequest: get error(%v)", err)
  184. continue
  185. }
  186. var res struct {
  187. Code int `json:"code"`
  188. }
  189. if err = client.Do(context.TODO(), req, &res); err != nil {
  190. if ecode.ServiceUnavailable.Equal(err) {
  191. b.Logf("Do: client.Do get error(%v) url: %s", err, realURL(req))
  192. }
  193. }
  194. }
  195. })
  196. }
  197. func TestRESTfulClient(t *testing.T) {
  198. c := &ServerConfig{
  199. Addr: "localhost:8082",
  200. Timeout: xtime.Duration(time.Second),
  201. ReadTimeout: xtime.Duration(time.Second),
  202. WriteTimeout: xtime.Duration(time.Second),
  203. }
  204. engine := Default()
  205. engine.GET("/mytest/1", func(ctx *Context) {
  206. time.Sleep(time.Millisecond * 500)
  207. ctx.JSON("", nil)
  208. })
  209. engine.GET("/mytest/2/1", func(ctx *Context) {
  210. time.Sleep(time.Millisecond * 500)
  211. // ctx.AbortWithStatus(http.StatusInternalServerError)
  212. ctx.JSON(nil, ecode.ServerErr)
  213. })
  214. engine.SetConfig(c)
  215. engine.Start()
  216. client := NewClient(
  217. &ClientConfig{
  218. App: &App{
  219. Key: "53e2fa226f5ad348",
  220. Secret: "3cf6bd1b0ff671021da5f424fea4b04a",
  221. },
  222. Dial: xtime.Duration(time.Second),
  223. Timeout: xtime.Duration(time.Second),
  224. KeepAlive: xtime.Duration(time.Second),
  225. Breaker: &breaker.Config{
  226. Window: 10 * xtime.Duration(time.Second),
  227. Sleep: 50 * xtime.Duration(time.Millisecond),
  228. Bucket: 10,
  229. Ratio: 0.5,
  230. Request: 100,
  231. },
  232. })
  233. var res struct {
  234. Code int `json:"code"`
  235. }
  236. if err := client.RESTfulGet(context.Background(), "http://localhost:8082/mytest/%d", "", nil, &res, 1); err != nil {
  237. t.Errorf("HTTPClient: expected error RESTfulGet err: %v", err)
  238. }
  239. if res.Code != 0 {
  240. t.Errorf("HTTPClient: expected code=0 but got %d", res.Code)
  241. }
  242. if err := client.RESTfulGet(context.Background(), "http://localhost:8082/mytest/%d/%d", "", nil, &res, 2, 1); err != nil {
  243. t.Errorf("HTTPClient: expected error RESTfulGet err: %v", err)
  244. }
  245. if res.Code != -500 {
  246. t.Errorf("HTTPClient: expected code=-500 but got %d", res.Code)
  247. }
  248. }
  249. func TestRaw(t *testing.T) {
  250. var (
  251. aid = 5463320
  252. uri = "http://api.bilibili.com/x/server/now"
  253. req *http.Request
  254. client *Client
  255. err error
  256. )
  257. client = NewClient(
  258. &ClientConfig{
  259. App: &App{
  260. Key: "53e2fa226f5ad348",
  261. Secret: "3cf6bd1b0ff671021da5f424fea4b04a",
  262. },
  263. Dial: xtime.Duration(time.Second),
  264. Timeout: xtime.Duration(time.Second),
  265. KeepAlive: xtime.Duration(time.Second),
  266. Breaker: &breaker.Config{
  267. Window: 10 * xtime.Duration(time.Second),
  268. Sleep: 50 * xtime.Duration(time.Millisecond),
  269. Bucket: 10,
  270. Ratio: 0.5,
  271. Request: 100,
  272. },
  273. })
  274. params := url.Values{}
  275. params.Set("aid", strconv.Itoa(aid))
  276. if req, err = client.NewRequest("GET", uri, "", params); err != nil {
  277. t.Errorf("client.NewRequest: get error(%v)", err)
  278. }
  279. var (
  280. bs []byte
  281. )
  282. if bs, err = client.Raw(context.TODO(), req); err != nil {
  283. t.Errorf("Do: client.Do get error(%v) url: %s", err, realURL(req))
  284. }
  285. t.Log(string(bs))
  286. }
  287. func TestJSON(t *testing.T) {
  288. var (
  289. aid = 5463320
  290. uri = "http://api.bilibili.com/x/server/now"
  291. req *http.Request
  292. client *Client
  293. err error
  294. )
  295. client = NewClient(
  296. &ClientConfig{
  297. App: &App{
  298. Key: "53e2fa226f5ad348",
  299. Secret: "3cf6bd1b0ff671021da5f424fea4b04a",
  300. },
  301. Dial: xtime.Duration(time.Second),
  302. Timeout: xtime.Duration(time.Second),
  303. KeepAlive: xtime.Duration(time.Second),
  304. Breaker: &breaker.Config{
  305. Window: 10 * xtime.Duration(time.Second),
  306. Sleep: 50 * xtime.Duration(time.Millisecond),
  307. Bucket: 10,
  308. Ratio: 0.5,
  309. Request: 100,
  310. },
  311. })
  312. params := url.Values{}
  313. params.Set("aid", strconv.Itoa(aid))
  314. if req, err = client.NewRequest("GET", uri, "", params); err != nil {
  315. t.Errorf("client.NewRequest: get error(%v)", err)
  316. }
  317. var res struct {
  318. Code int `json:"code"`
  319. }
  320. if err = client.Do(context.TODO(), req, &res); err != nil {
  321. t.Errorf("Do: client.Do get error(%v) url: %s", err, realURL(req))
  322. }
  323. }
  324. func TestPB(t *testing.T) {
  325. var (
  326. uri = "http://172.18.33.143:13500/playurl/batch"
  327. req *http.Request
  328. client *Client
  329. err error
  330. )
  331. client = NewClient(
  332. &ClientConfig{
  333. App: &App{
  334. Key: "53e2fa226f5ad348",
  335. Secret: "3cf6bd1b0ff671021da5f424fea4b04a",
  336. },
  337. Dial: xtime.Duration(time.Second),
  338. Timeout: xtime.Duration(time.Second),
  339. KeepAlive: xtime.Duration(time.Second),
  340. Breaker: &breaker.Config{
  341. Window: 10 * xtime.Duration(time.Second),
  342. Sleep: 50 * xtime.Duration(time.Millisecond),
  343. Bucket: 10,
  344. Ratio: 0.5,
  345. Request: 100,
  346. },
  347. })
  348. params := url.Values{}
  349. params.Set("cid", "10108859,10108860")
  350. params.Set("uip", "222.73.196.18")
  351. params.Set("qn", "16")
  352. params.Set("platform", "html5")
  353. params.Set("layout", "pb")
  354. if req, err = client.NewRequest("GET", uri, "", params); err != nil {
  355. t.Errorf("client.NewRequest: get error(%v)", err)
  356. }
  357. var res = new(tests.BvcResponseMsg)
  358. if err = client.PB(context.TODO(), req, res); err != nil {
  359. t.Errorf("Do: client.Do get error(%v) url: %s", err, realURL(req))
  360. }
  361. t.Log(res)
  362. }