location_resolver_test.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. package endpoints
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io/ioutil"
  6. "net/http"
  7. "strconv"
  8. "sync"
  9. "testing"
  10. "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
  11. "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
  12. "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
  13. "github.com/stretchr/testify/assert"
  14. )
  15. func TestLocationResolver_GetName(t *testing.T) {
  16. resolver := &LocationResolver{}
  17. assert.Equal(t, "location resolver", resolver.GetName())
  18. }
  19. // cases from later commit
  20. func TestLocationResolver_TryResolve_EmptyLocationProduct(t *testing.T) {
  21. resolver := &LocationResolver{}
  22. resolveParam := &ResolveParam{}
  23. endpoint, support, err := resolver.TryResolve(resolveParam)
  24. assert.Nil(t, err)
  25. assert.Equal(t, "", endpoint)
  26. assert.Equal(t, false, support)
  27. }
  28. func TestLocationResolver_TryResolve_LocationWithError(t *testing.T) {
  29. resolver := &LocationResolver{}
  30. resolveParam := &ResolveParam{
  31. LocationProduct: "ecs",
  32. RegionId: "cn-hangzhou",
  33. Product: "ecs",
  34. CommonApi: func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
  35. err = errors.NewClientError("SDK.MockError", "Mock error", nil)
  36. return
  37. },
  38. }
  39. endpoint, support, err := resolver.TryResolve(resolveParam)
  40. assert.Equal(t, "", endpoint)
  41. assert.Equal(t, false, support)
  42. assert.Equal(t, "[SDK.MockError] Mock error", err.Error())
  43. }
  44. func makeHTTPResponse(statusCode int, content string) (res *http.Response) {
  45. header := make(http.Header)
  46. status := strconv.Itoa(statusCode)
  47. res = &http.Response{
  48. Proto: "HTTP/1.1",
  49. ProtoMajor: 1,
  50. Header: header,
  51. StatusCode: statusCode,
  52. Status: status + " " + http.StatusText(statusCode),
  53. }
  54. res.Header = make(http.Header)
  55. res.Body = ioutil.NopCloser(bytes.NewReader([]byte(content)))
  56. return
  57. }
  58. func TestLocationResolver_TryResolve_Location_With_Endpoint2(t *testing.T) {
  59. resolver := &LocationResolver{}
  60. resolveParam := &ResolveParam{
  61. LocationProduct: "ecs3",
  62. RegionId: "cn-hangzhou",
  63. Product: "ecs3",
  64. CommonApi: func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
  65. response = responses.NewCommonResponse()
  66. responses.Unmarshal(response, makeHTTPResponse(200, `{
  67. "Endpoints":{
  68. "Endpoint":[
  69. {
  70. "Protocols":{
  71. "Protocols":["HTTP","HTTPS"]
  72. },
  73. "Type":"openAPI",
  74. "Namespace":"26842",
  75. "Id":"cn-beijing",
  76. "SerivceCode":"ecs",
  77. "Endpoint":"ecs-cn-hangzhou.aliyuncs.com"
  78. }
  79. ]
  80. },
  81. "RequestId":"B3B36D8E-5029-42E3-B1FB-9B687F7591DA",
  82. "Success":true
  83. }`), "JSON")
  84. return
  85. },
  86. }
  87. endpoint, support, err := resolver.TryResolve(resolveParam)
  88. assert.Equal(t, "ecs-cn-hangzhou.aliyuncs.com", endpoint)
  89. assert.Equal(t, true, support)
  90. assert.Nil(t, err)
  91. // hit the cache
  92. lastClearTimePerProduct.Set(resolveParam.Product+"#"+resolveParam.RegionId, int64(0))
  93. endpoint, support, err = resolver.TryResolve(resolveParam)
  94. assert.Equal(t, "ecs-cn-hangzhou.aliyuncs.com", endpoint)
  95. assert.Equal(t, true, support)
  96. assert.Nil(t, err)
  97. resolveParam.LocationEndpointType = "openAPI"
  98. lastClearTimePerProduct.Set(resolveParam.Product+"#"+resolveParam.RegionId, 0)
  99. endpoint, support, err = resolver.TryResolve(resolveParam)
  100. assert.Equal(t, "ecs-cn-hangzhou.aliyuncs.com", endpoint)
  101. assert.Equal(t, true, support)
  102. assert.Nil(t, err)
  103. }
  104. func TestLocationResolver_TryResolve_Location_With_EmptyEndpoint(t *testing.T) {
  105. resolver := &LocationResolver{}
  106. resolveParam := &ResolveParam{
  107. LocationProduct: "ecs2",
  108. RegionId: "cn-hangzhou",
  109. Product: "ecs2",
  110. CommonApi: func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
  111. response = responses.NewCommonResponse()
  112. responses.Unmarshal(response, makeHTTPResponse(200, `{"Success":true,"RequestId":"request id","Endpoints":{"Endpoint":[{"Endpoint":""}]}}`), "JSON")
  113. return
  114. },
  115. }
  116. endpoint, support, err := resolver.TryResolve(resolveParam)
  117. assert.Equal(t, "", endpoint)
  118. assert.Equal(t, false, support)
  119. assert.Nil(t, err)
  120. }
  121. func TestLocationResolver_TryResolve_LocationWith404(t *testing.T) {
  122. resolver := &LocationResolver{}
  123. resolveParam := &ResolveParam{
  124. LocationProduct: "ecs",
  125. RegionId: "cn-hangzhou",
  126. Product: "ecs",
  127. CommonApi: func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
  128. response = responses.NewCommonResponse()
  129. responses.Unmarshal(response, makeHTTPResponse(404, "content"), "JSON")
  130. return
  131. },
  132. }
  133. endpoint, support, err := resolver.TryResolve(resolveParam)
  134. assert.Equal(t, "", endpoint)
  135. assert.Equal(t, false, support)
  136. assert.Nil(t, err)
  137. }
  138. func TestLocationResolver_TryResolve_LocationWith200InvalidJSON(t *testing.T) {
  139. resolver := &LocationResolver{}
  140. resolveParam := &ResolveParam{
  141. LocationProduct: "ecs",
  142. RegionId: "cn-hangzhou",
  143. Product: "ecs",
  144. CommonApi: func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
  145. response = responses.NewCommonResponse()
  146. responses.Unmarshal(response, makeHTTPResponse(200, "content"), "JSON")
  147. return
  148. },
  149. }
  150. endpoint, support, err := resolver.TryResolve(resolveParam)
  151. assert.Equal(t, "", endpoint)
  152. assert.Equal(t, false, support)
  153. assert.Equal(t, "invalid character 'c' looking for beginning of value", err.Error())
  154. }
  155. func TestLocationResolver_TryResolve_LocationWith200ValidJSON(t *testing.T) {
  156. resolver := &LocationResolver{}
  157. resolveParam := &ResolveParam{
  158. LocationProduct: "ecs",
  159. RegionId: "cn-hangzhou",
  160. Product: "ecs",
  161. CommonApi: func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
  162. response = responses.NewCommonResponse()
  163. responses.Unmarshal(response, makeHTTPResponse(200, `{"Code":"Success","RequestId":"request id"}`), "JSON")
  164. return
  165. },
  166. }
  167. endpoint, support, err := resolver.TryResolve(resolveParam)
  168. assert.Equal(t, "", endpoint)
  169. assert.Equal(t, false, support)
  170. assert.Nil(t, err)
  171. // assert.Equal(t, "json: cannot unmarshal array into Go struct field GetEndpointResponse.Endpoints of type endpoints.EndpointsObj", err.Error())
  172. }
  173. func TestLocationResolver_TryResolve_LocationWith200(t *testing.T) {
  174. resolver := &LocationResolver{}
  175. resolveParam := &ResolveParam{
  176. LocationProduct: "ecs",
  177. RegionId: "cn-hangzhou",
  178. Product: "ecs",
  179. CommonApi: func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
  180. response = responses.NewCommonResponse()
  181. responses.Unmarshal(response, makeHTTPResponse(200, `{"Success":true,"RequestId":"request id","Endpoints":{"Endpoint":[]}}`), "JSON")
  182. return
  183. },
  184. }
  185. endpoint, support, err := resolver.TryResolve(resolveParam)
  186. assert.Equal(t, "", endpoint)
  187. assert.Equal(t, false, support)
  188. assert.Nil(t, err)
  189. }
  190. func resovleSucc(i int) (ep string, isSupport bool, err error) {
  191. resolver := &LocationResolver{}
  192. resolveParam := &ResolveParam{
  193. LocationProduct: "ecs",
  194. RegionId: fmt.Sprintf("cn-hangzhou%d", i),
  195. Product: "ecs",
  196. CommonApi: func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
  197. response = responses.NewCommonResponse()
  198. responses.Unmarshal(response, makeHTTPResponse(200, `{"Success":true,"RequestId":"request id","Endpoints":{"Endpoint":[{"Endpoint":"domain.com"}]}}`), "JSON")
  199. return
  200. },
  201. }
  202. endpoint, support, err := resolver.TryResolve(resolveParam)
  203. return endpoint, support, err
  204. }
  205. // concurrent cases
  206. func TestResolveConcurrent(t *testing.T) {
  207. current := len(endpointCache.cache)
  208. cnt := 50
  209. var wg sync.WaitGroup
  210. for i := 0; i < cnt; i++ {
  211. wg.Add(1)
  212. go func(k int) {
  213. defer wg.Done()
  214. cachedKey := fmt.Sprintf("ecs#cn-hangzhou%d", k)
  215. for j := 0; j < 50; j++ {
  216. endpoint, support, err := resovleSucc(k)
  217. assert.Equal(t, "domain.com", endpointCache.Get(cachedKey))
  218. assert.Equal(t, "domain.com", endpoint)
  219. assert.Equal(t, true, support)
  220. assert.Nil(t, err)
  221. }
  222. }(i)
  223. }
  224. wg.Wait()
  225. assert.Equal(t, (current + cnt), len(endpointCache.cache))
  226. // hit cache and concurrent get
  227. for i := 0; i < cnt; i++ {
  228. wg.Add(1)
  229. go func(k int) {
  230. defer wg.Done()
  231. cachedKey := fmt.Sprintf("ecs#cn-hangzhou%d", k)
  232. for j := 0; j < cnt; j++ {
  233. assert.Equal(t, "domain.com", endpointCache.Get(cachedKey))
  234. endpoint, support, err := resovleSucc(k)
  235. assert.Equal(t, "domain.com", endpoint)
  236. assert.Equal(t, true, support)
  237. assert.Nil(t, err)
  238. }
  239. }(i)
  240. wg.Wait()
  241. }
  242. assert.Equal(t, (current + cnt), len(endpointCache.cache))
  243. }