context_test.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. // +build go1.7
  2. // Copyright (c) 2015-2019 Jeevanandam M (jeeva@myjeeva.com)
  3. // 2016 Andrew Grigorev (https://github.com/ei-grad)
  4. // All rights reserved.
  5. // resty source code and usage is governed by a MIT style
  6. // license that can be found in the LICENSE file.
  7. package resty
  8. import (
  9. "context"
  10. "net/http"
  11. "strings"
  12. "sync/atomic"
  13. "testing"
  14. "time"
  15. )
  16. func TestSetContext(t *testing.T) {
  17. ts := createGetServer(t)
  18. defer ts.Close()
  19. resp, err := R().
  20. SetContext(context.Background()).
  21. Get(ts.URL + "/")
  22. assertError(t, err)
  23. assertEqual(t, http.StatusOK, resp.StatusCode())
  24. assertEqual(t, "200 OK", resp.Status())
  25. assertEqual(t, true, resp.Body() != nil)
  26. assertEqual(t, "TestGet: text response", resp.String())
  27. logResponse(t, resp)
  28. }
  29. func TestSetContextWithError(t *testing.T) {
  30. ts := createGetServer(t)
  31. defer ts.Close()
  32. resp, err := dcr().
  33. SetContext(context.Background()).
  34. Get(ts.URL + "/mypage")
  35. assertError(t, err)
  36. assertEqual(t, http.StatusBadRequest, resp.StatusCode())
  37. assertEqual(t, "", resp.String())
  38. logResponse(t, resp)
  39. }
  40. func TestSetContextCancel(t *testing.T) {
  41. ch := make(chan struct{})
  42. ts := createTestServer(func(w http.ResponseWriter, r *http.Request) {
  43. defer func() {
  44. ch <- struct{}{} // tell test request is finished
  45. }()
  46. t.Logf("Server: %v %v", r.Method, r.URL.Path)
  47. ch <- struct{}{}
  48. <-ch // wait for client to finish request
  49. n, err := w.Write([]byte("TestSetContextCancel: response"))
  50. // FIXME? test server doesn't handle request cancellation
  51. t.Logf("Server: wrote %d bytes", n)
  52. t.Logf("Server: err is %v ", err)
  53. })
  54. defer ts.Close()
  55. ctx, cancel := context.WithCancel(context.Background())
  56. go func() {
  57. <-ch // wait for server to start request handling
  58. cancel()
  59. }()
  60. _, err := R().
  61. SetContext(ctx).
  62. Get(ts.URL + "/")
  63. ch <- struct{}{} // tell server to continue request handling
  64. <-ch // wait for server to finish request handling
  65. t.Logf("Error: %v", err)
  66. if !errIsContextCanceled(err) {
  67. t.Errorf("Got unexpected error: %v", err)
  68. }
  69. }
  70. func TestSetContextCancelRetry(t *testing.T) {
  71. reqCount := 0
  72. ch := make(chan struct{})
  73. ts := createTestServer(func(w http.ResponseWriter, r *http.Request) {
  74. reqCount++
  75. defer func() {
  76. ch <- struct{}{} // tell test request is finished
  77. }()
  78. t.Logf("Server: %v %v", r.Method, r.URL.Path)
  79. ch <- struct{}{}
  80. <-ch // wait for client to finish request
  81. n, err := w.Write([]byte("TestSetContextCancel: response"))
  82. // FIXME? test server doesn't handle request cancellation
  83. t.Logf("Server: wrote %d bytes", n)
  84. t.Logf("Server: err is %v ", err)
  85. })
  86. defer ts.Close()
  87. ctx, cancel := context.WithCancel(context.Background())
  88. go func() {
  89. <-ch // wait for server to start request handling
  90. cancel()
  91. }()
  92. c := dc()
  93. c.SetHTTPMode().
  94. SetTimeout(time.Second * 3).
  95. SetRetryCount(3)
  96. _, err := c.R().
  97. SetContext(ctx).
  98. Get(ts.URL + "/")
  99. ch <- struct{}{} // tell server to continue request handling
  100. <-ch // wait for server to finish request handling
  101. t.Logf("Error: %v", err)
  102. if !errIsContextCanceled(err) {
  103. t.Errorf("Got unexpected error: %v", err)
  104. }
  105. if reqCount != 1 {
  106. t.Errorf("Request was retried %d times instead of 1", reqCount)
  107. }
  108. }
  109. func TestSetContextCancelWithError(t *testing.T) {
  110. ch := make(chan struct{})
  111. ts := createTestServer(func(w http.ResponseWriter, r *http.Request) {
  112. defer func() {
  113. ch <- struct{}{} // tell test request is finished
  114. }()
  115. t.Logf("Server: %v %v", r.Method, r.URL.Path)
  116. t.Log("Server: sending StatusBadRequest response")
  117. w.WriteHeader(http.StatusBadRequest)
  118. ch <- struct{}{}
  119. <-ch // wait for client to finish request
  120. n, err := w.Write([]byte("TestSetContextCancelWithError: response"))
  121. // FIXME? test server doesn't handle request cancellation
  122. t.Logf("Server: wrote %d bytes", n)
  123. t.Logf("Server: err is %v ", err)
  124. })
  125. defer ts.Close()
  126. ctx, cancel := context.WithCancel(context.Background())
  127. go func() {
  128. <-ch // wait for server to start request handling
  129. cancel()
  130. }()
  131. _, err := R().
  132. SetContext(ctx).
  133. Get(ts.URL + "/")
  134. ch <- struct{}{} // tell server to continue request handling
  135. <-ch // wait for server to finish request handling
  136. t.Logf("Error: %v", err)
  137. if !errIsContextCanceled(err) {
  138. t.Errorf("Got unexpected error: %v", err)
  139. }
  140. }
  141. func TestClientRetryWithSetContext(t *testing.T) {
  142. var attemptctx int32
  143. ts := createTestServer(func(w http.ResponseWriter, r *http.Request) {
  144. t.Logf("Method: %v", r.Method)
  145. t.Logf("Path: %v", r.URL.Path)
  146. attp := atomic.AddInt32(&attemptctx, 1)
  147. if attp <= 3 {
  148. time.Sleep(time.Second * 2)
  149. }
  150. _, _ = w.Write([]byte("TestClientRetry page"))
  151. })
  152. defer ts.Close()
  153. c := dc()
  154. c.SetHTTPMode().
  155. SetTimeout(time.Second * 1).
  156. SetRetryCount(3)
  157. _, err := c.R().
  158. SetContext(context.Background()).
  159. Get(ts.URL + "/")
  160. assertEqual(t, true, strings.HasPrefix(err.Error(), "Get "+ts.URL+"/"))
  161. }