github.com/alibabacloud-go/tea@v1.3.10/tea/tea_test.go (about) 1 package tea 2 3 import ( 4 "bytes" 5 "context" 6 "errors" 7 "io" 8 "io/ioutil" 9 "net/http" 10 "os" 11 "reflect" 12 "strconv" 13 "strings" 14 "sync" 15 "testing" 16 "time" 17 18 "github.com/alibabacloud-go/tea/utils" 19 ) 20 21 var runtimeObj = map[string]interface{}{ 22 "ignoreSSL": false, 23 "readTimeout": 0, 24 "localAddr": "", 25 "httpProxy": "", 26 "httpsProxy": "", 27 "maxIdleConns": 0, 28 "socks5Proxy": "", 29 "socks5NetWork": "", 30 "listener": &Progresstest{}, 31 "tracker": &utils.ReaderTracker{CompletedBytes: int64(10)}, 32 "logger": utils.NewLogger("info", "", &bytes.Buffer{}, "{time}"), 33 } 34 35 var key = `-----BEGIN RSA PRIVATE KEY----- 36 MIIBPAIBAAJBAN5I1VCLYr2IlTLrFpwUGcnwl8yi6V8Mdw+myxfusNgEWiH/FQ4T 37 AZsIveiLOz9Gcc8m2mZSxst2qGII00scpiECAwEAAQJBAJZEhnA8yjN28eXKJy68 38 J/LsQrKEL1+h/ZsHFqTHJ6XfiA0CXjbjPsa4jEbpyilMTSgUyoKdJ512ioeco2n6 39 xUECIQD/JUHaKSuxz55t3efKdppqfopb92mJ2NuPJgrJI70OCwIhAN8HZ0bzr/4a 40 DLvYCDUKvOj3GzsV1dtBwWuHBaZEafQDAiEAtTnrel//7z5/U55ow4BW0gmrkQM9 41 bXIhEZ59zryZzl0CIQDFmBqRCu9eshecCP7kd3n88IjopSTOV4iUypBfyXcRnwIg 42 eXNxUx+BCu2We36+c0deE2+vizL1s6f5XhE6l4bqtiM= 43 -----END RSA PRIVATE KEY-----` 44 var cert = `-----BEGIN CERTIFICATE----- 45 MIIBvDCCAWYCCQDKjNYQxar0mjANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQGEwJh 46 czEMMAoGA1UECAwDYXNmMQwwCgYDVQQHDANzYWQxCzAJBgNVBAoMAnNkMQ0wCwYD 47 VQQLDARxd2VyMQswCQYDVQQDDAJzZjERMA8GCSqGSIb3DQEJARYCd2UwHhcNMjAx 48 MDE5MDI0MDMwWhcNMzAxMDE3MDI0MDMwWjBlMQswCQYDVQQGEwJhczEMMAoGA1UE 49 CAwDYXNmMQwwCgYDVQQHDANzYWQxCzAJBgNVBAoMAnNkMQ0wCwYDVQQLDARxd2Vy 50 MQswCQYDVQQDDAJzZjERMA8GCSqGSIb3DQEJARYCd2UwXDANBgkqhkiG9w0BAQEF 51 AANLADBIAkEA3kjVUItivYiVMusWnBQZyfCXzKLpXwx3D6bLF+6w2ARaIf8VDhMB 52 mwi96Is7P0ZxzybaZlLGy3aoYgjTSxymIQIDAQABMA0GCSqGSIb3DQEBCwUAA0EA 53 ZjePopbFugNK0US1MM48V1S2petIsEcxbZBEk/wGqIzrY4RCFKMtbtPSgTDUl3D9 54 XePemktG22a54ItVJ5FpcQ== 55 -----END CERTIFICATE-----` 56 var ca = `-----BEGIN CERTIFICATE----- 57 MIIBuDCCAWICCQCLw4OWpjlJCDANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJm 58 ZDEMMAoGA1UECAwDYXNkMQswCQYDVQQHDAJxcjEKMAgGA1UECgwBZjEMMAoGA1UE 59 CwwDc2RhMQswCQYDVQQDDAJmZDESMBAGCSqGSIb3DQEJARYDYXNkMB4XDTIwMTAx 60 OTAyNDQwNFoXDTIzMDgwOTAyNDQwNFowYzELMAkGA1UEBhMCZmQxDDAKBgNVBAgM 61 A2FzZDELMAkGA1UEBwwCcXIxCjAIBgNVBAoMAWYxDDAKBgNVBAsMA3NkYTELMAkG 62 A1UEAwwCZmQxEjAQBgkqhkiG9w0BCQEWA2FzZDBcMA0GCSqGSIb3DQEBAQUAA0sA 63 MEgCQQCxXZTl5IO61Lqd0fBBOSy7ER1gsdA0LkvflP5HEaQygjecLGfrAtD/DWu0 64 /sxCcBVnQRoP9Yp0ijHJwgXvBnrNAgMBAAEwDQYJKoZIhvcNAQELBQADQQBJF+/4 65 DEMilhlFY+o9mqCygFVxuvHtQVhpPS938H2h7/P6pXN65jK2Y5hHefZEELq9ulQe 66 91iBwaQ4e9racCgP 67 -----END CERTIFICATE-----` 68 69 type test struct { 70 Key string `json:"key,omitempty"` 71 Body []byte `json:"body,omitempty"` 72 } 73 74 type PrettifyTest struct { 75 name string 76 Strs []string 77 Nums8 []int8 78 Unum8 []uint8 79 Value string 80 Mapvalue map[string]string 81 } 82 83 type validateTest struct { 84 Num1 *int `json:"num1,omitempty" require:"true" minimum:"2"` 85 Num2 *int `json:"num2,omitempty" maximum:"6"` 86 Name1 *string `json:"name1,omitempty" maxLength:"4"` 87 Name2 *string `json:"name2,omitempty" minLength:"2"` 88 Str *string `json:"str,omitempty" pattern:"[a-d]*" maxLength:"4"` 89 MaxLength *errMaxLength `json:"MaxLength,omitempty"` 90 MinLength *errMinLength `json:"MinLength,omitempty"` 91 Maximum *errMaximum `json:"Maximum,omitempty"` 92 Minimum *errMinimum `json:"Minimum,omitempty"` 93 MaxItems *errMaxItems `json:"MaxItems,omitempty"` 94 MinItems *errMinItems `json:"MinItems,omitempty"` 95 List []*string `json:"list,omitempty" pattern:"[a-d]*" minItems:"2" maxItems:"3" maxLength:"4"` 96 } 97 98 type errMaxLength struct { 99 Num *int `json:"num" maxLength:"a"` 100 } 101 102 type errMinLength struct { 103 Num *int `json:"num" minLength:"a"` 104 } 105 106 type errMaximum struct { 107 Num *int `json:"num" maximum:"a"` 108 } 109 110 type errMinimum struct { 111 Num *int `json:"num" minimum:"a"` 112 } 113 114 type errMaxItems struct { 115 NumMax []*int `json:"num" maxItems:"a"` 116 } 117 118 type errMinItems struct { 119 NumMin []*int `json:"num" minItems:"a"` 120 } 121 122 type Progresstest struct { 123 } 124 125 func (progress *Progresstest) ProgressChanged(event *utils.ProgressEvent) { 126 } 127 128 func mockResponse(statusCode int, content string, mockerr error) (res *http.Response, err error) { 129 status := strconv.Itoa(statusCode) 130 res = &http.Response{ 131 Proto: "HTTP/1.1", 132 ProtoMajor: 1, 133 Header: map[string][]string{"TEA": []string{"test"}}, 134 StatusCode: statusCode, 135 Status: status + " " + http.StatusText(statusCode), 136 } 137 res.Body = ioutil.NopCloser(bytes.NewReader([]byte(content))) 138 err = mockerr 139 return 140 } 141 142 func TestCastError(t *testing.T) { 143 err := NewCastError(String("cast error")) 144 utils.AssertEqual(t, "cast error", err.Error()) 145 } 146 147 func TestRequest(t *testing.T) { 148 request := NewRequest() 149 utils.AssertNotNil(t, request) 150 } 151 152 func TestResponse(t *testing.T) { 153 httpresponse := &http.Response{ 154 Body: ioutil.NopCloser(strings.NewReader("response")), 155 } 156 response := NewResponse(httpresponse) 157 utils.AssertNotNil(t, response) 158 159 body, err := response.ReadBody() 160 utils.AssertEqual(t, "response", string(body)) 161 utils.AssertNil(t, err) 162 } 163 164 func TestConvert(t *testing.T) { 165 in := map[string]interface{}{ 166 "key": "value", 167 "body": []byte("test"), 168 } 169 out := new(test) 170 err := Convert(in, &out) 171 utils.AssertNil(t, err) 172 utils.AssertEqual(t, "value", out.Key) 173 utils.AssertEqual(t, "test", string(out.Body)) 174 } 175 176 func TestConvertType(t *testing.T) { 177 in := map[string]interface{}{ 178 "key": 123, 179 "body": []byte("test"), 180 } 181 out := new(test) 182 err := Convert(in, &out) 183 utils.AssertNil(t, err) 184 utils.AssertEqual(t, "123", out.Key) 185 utils.AssertEqual(t, "test", string(out.Body)) 186 } 187 188 func TestRuntimeObject(t *testing.T) { 189 runtimeobject := NewRuntimeObject(nil) 190 utils.AssertNil(t, runtimeobject.IgnoreSSL) 191 192 runtimeobject = NewRuntimeObject(runtimeObj) 193 utils.AssertEqual(t, false, BoolValue(runtimeobject.IgnoreSSL)) 194 } 195 196 func TestSDKError(t *testing.T) { 197 err := NewSDKError(map[string]interface{}{ 198 "code": "code", 199 "statusCode": 404, 200 "message": "message", 201 "data": map[string]interface{}{ 202 "httpCode": "404", 203 "requestId": "dfadfa32cgfdcasd4313", 204 "hostId": "github.com/alibabacloud/tea", 205 "recommend": "https://中文?q=a.b&product=c&requestId=123", 206 }, 207 "description": "description", 208 "accessDeniedDetail": map[string]interface{}{ 209 "AuthAction": "ram:ListUsers", 210 "AuthPrincipalType": "SubUser", 211 "PolicyType": "ResourceGroupLevelIdentityBassdPolicy", 212 "NoPermissionType": "ImplicitDeny", 213 "UserId": 123, 214 }, 215 }) 216 utils.AssertNotNil(t, err) 217 utils.AssertEqual(t, "SDKError:\n StatusCode: 404\n Code: code\n Message: message\n Data: {\"hostId\":\"github.com/alibabacloud/tea\",\"httpCode\":\"404\",\"recommend\":\"https://中文?q=a.b&product=c&requestId=123\",\"requestId\":\"dfadfa32cgfdcasd4313\"}\n", err.Error()) 218 219 err.SetErrMsg("test") 220 utils.AssertEqual(t, "test", err.Error()) 221 utils.AssertEqual(t, 404, *err.StatusCode) 222 utils.AssertEqual(t, "description", *err.Description) 223 utils.AssertEqual(t, "ImplicitDeny", err.AccessDeniedDetail["NoPermissionType"]) 224 utils.AssertEqual(t, 123, err.AccessDeniedDetail["UserId"]) 225 226 err = NewSDKError(map[string]interface{}{ 227 "statusCode": "404", 228 "data": map[string]interface{}{ 229 "statusCode": 500, 230 }, 231 }) 232 utils.AssertNotNil(t, err) 233 utils.AssertEqual(t, 404, *err.StatusCode) 234 235 err = NewSDKError(map[string]interface{}{ 236 "data": map[string]interface{}{ 237 "statusCode": 500, 238 }, 239 }) 240 utils.AssertNotNil(t, err) 241 utils.AssertEqual(t, 500, *err.StatusCode) 242 243 err = NewSDKError(map[string]interface{}{ 244 "data": map[string]interface{}{ 245 "statusCode": Int(500), 246 }, 247 }) 248 utils.AssertNotNil(t, err) 249 utils.AssertEqual(t, 500, *err.StatusCode) 250 251 err = NewSDKError(map[string]interface{}{ 252 "data": map[string]interface{}{ 253 "statusCode": "500", 254 }, 255 }) 256 utils.AssertNotNil(t, err) 257 utils.AssertEqual(t, 500, *err.StatusCode) 258 259 err = NewSDKError(map[string]interface{}{ 260 "code": "code", 261 "message": "message", 262 "data": map[string]interface{}{ 263 "requestId": "dfadfa32cgfdcasd4313", 264 }, 265 }) 266 utils.AssertNotNil(t, err) 267 utils.AssertNil(t, err.StatusCode) 268 269 err = NewSDKError(map[string]interface{}{ 270 "code": "code", 271 "message": "message", 272 "data": "string data", 273 }) 274 utils.AssertNotNil(t, err) 275 utils.AssertNotNil(t, err.Data) 276 utils.AssertNil(t, err.StatusCode) 277 } 278 279 func TestSDKErrorCode404(t *testing.T) { 280 err := NewSDKError(map[string]interface{}{ 281 "statusCode": 404, 282 "code": "NOTFOUND", 283 "message": "message", 284 }) 285 utils.AssertNotNil(t, err) 286 utils.AssertEqual(t, "SDKError:\n StatusCode: 404\n Code: NOTFOUND\n Message: message\n Data: \n", err.Error()) 287 } 288 289 func TestToObject(t *testing.T) { 290 str := "{sdsfdsd:" 291 result := ToObject(str) 292 utils.AssertNil(t, result) 293 294 input := map[string]string{ 295 "name": "test", 296 } 297 result = ToObject(input) 298 utils.AssertEqual(t, "test", result["name"].(string)) 299 } 300 301 func TestAllowRetry(t *testing.T) { 302 allow := AllowRetry(nil, Int(0)) 303 utils.AssertEqual(t, true, BoolValue(allow)) 304 305 allow = AllowRetry(nil, Int(1)) 306 utils.AssertEqual(t, false, BoolValue(allow)) 307 308 input := map[string]interface{}{ 309 "retryable": false, 310 "maxAttempts": 2, 311 } 312 allow = AllowRetry(input, Int(1)) 313 utils.AssertEqual(t, false, BoolValue(allow)) 314 315 input["retryable"] = true 316 allow = AllowRetry(input, Int(3)) 317 utils.AssertEqual(t, false, BoolValue(allow)) 318 319 input["retryable"] = true 320 allow = AllowRetry(input, Int(1)) 321 utils.AssertEqual(t, true, BoolValue(allow)) 322 } 323 324 func TestMerge(t *testing.T) { 325 in := map[string]*string{ 326 "tea": String("test"), 327 } 328 valid := map[string]interface{}{ 329 "valid": "test", 330 } 331 invalidStr := "sdfdg" 332 result := Merge(in, valid, invalidStr) 333 utils.AssertEqual(t, "test", StringValue(result["tea"])) 334 utils.AssertEqual(t, "test", StringValue(result["valid"])) 335 336 result = Merge(nil) 337 utils.AssertEqual(t, map[string]*string{}, result) 338 } 339 340 type Test struct { 341 Msg *string `json:"Msg,omitempty"` 342 Cast *CastError `json:"Cast,omitempty"` 343 ListPtr []*string `json:"ListPtr,omitempty"` 344 List []string `json:"List,omitempty"` 345 CastList []CastError `json:"CastList,omitempty"` 346 CastListPtr []*CastError `json:"CastListPtr,omitempty"` 347 Reader io.Reader 348 Inter interface{} 349 } 350 351 func TestToMap(t *testing.T) { 352 in := map[string]*string{ 353 "tea": String("test"), 354 "nil": nil, 355 } 356 result := ToMap(in) 357 utils.AssertEqual(t, "test", result["tea"]) 358 utils.AssertNil(t, result["nil"]) 359 360 validMap := map[string]interface{}{ 361 "valid": "test", 362 } 363 result = ToMap(validMap) 364 utils.AssertEqual(t, "test", result["valid"]) 365 366 valid := &Test{ 367 Msg: String("tea"), 368 Cast: &CastError{ 369 Message: String("message"), 370 }, 371 ListPtr: StringSlice([]string{"test", ""}), 372 List: []string{"list"}, 373 CastListPtr: []*CastError{ 374 &CastError{ 375 Message: String("CastListPtr"), 376 }, 377 nil, 378 }, 379 CastList: []CastError{ 380 CastError{ 381 Message: String("CastList"), 382 }, 383 }, 384 Reader: strings.NewReader(""), 385 Inter: 10, 386 } 387 result = ToMap(valid) 388 utils.AssertEqual(t, "tea", result["Msg"]) 389 utils.AssertNil(t, result["Reader"]) 390 utils.AssertEqual(t, map[string]interface{}{"Message": "message"}, result["Cast"]) 391 utils.AssertEqual(t, []interface{}{"test", ""}, result["ListPtr"]) 392 utils.AssertEqual(t, []interface{}{"list"}, result["List"]) 393 utils.AssertEqual(t, []interface{}{map[string]interface{}{"Message": "CastListPtr"}}, result["CastListPtr"]) 394 utils.AssertEqual(t, []interface{}{map[string]interface{}{"Message": "CastList"}}, result["CastList"]) 395 396 valid1 := &Test{ 397 Msg: String("tea"), 398 } 399 result = ToMap(valid1) 400 utils.AssertEqual(t, "tea", result["Msg"]) 401 402 validStr := String(`{"test":"ok"}`) 403 result = ToMap(validStr) 404 utils.AssertEqual(t, "ok", result["test"]) 405 406 validStr1 := String(`{"test":"ok","num":1}`) 407 result = ToMap(validStr1) 408 utils.AssertEqual(t, "ok", result["test"]) 409 410 result = ToMap([]byte(StringValue(validStr))) 411 utils.AssertEqual(t, "ok", result["test"]) 412 413 result = ToMap([]byte(StringValue(validStr1))) 414 utils.AssertEqual(t, "ok", result["test"]) 415 416 invalidStr := "sdfdg" 417 result = ToMap(invalidStr) 418 utils.AssertEqual(t, map[string]interface{}{}, result) 419 420 result = ToMap(10) 421 utils.AssertEqual(t, map[string]interface{}{}, result) 422 423 result = ToMap(nil) 424 utils.AssertNil(t, result) 425 } 426 427 func Test_Retryable(t *testing.T) { 428 ifRetry := Retryable(nil) 429 utils.AssertEqual(t, false, BoolValue(ifRetry)) 430 431 err := errors.New("tea") 432 ifRetry = Retryable(err) 433 utils.AssertEqual(t, true, BoolValue(ifRetry)) 434 435 errmsg := map[string]interface{}{ 436 "code": "err", 437 } 438 err = NewSDKError(errmsg) 439 ifRetry = Retryable(err) 440 utils.AssertEqual(t, false, BoolValue(ifRetry)) 441 442 errmsg["statusCode"] = 400 443 err = NewSDKError(errmsg) 444 ifRetry = Retryable(err) 445 utils.AssertEqual(t, false, BoolValue(ifRetry)) 446 447 errmsg["statusCode"] = "400" 448 err = NewSDKError(errmsg) 449 ifRetry = Retryable(err) 450 utils.AssertEqual(t, false, BoolValue(ifRetry)) 451 452 errmsg["statusCode"] = 500 453 err = NewSDKError(errmsg) 454 ifRetry = Retryable(err) 455 utils.AssertEqual(t, true, BoolValue(ifRetry)) 456 457 errmsg["statusCode"] = "500" 458 err = NewSDKError(errmsg) 459 ifRetry = Retryable(err) 460 utils.AssertEqual(t, true, BoolValue(ifRetry)) 461 462 errmsg["statusCode"] = "test" 463 err = NewSDKError(errmsg) 464 ifRetry = Retryable(err) 465 utils.AssertEqual(t, false, BoolValue(ifRetry)) 466 } 467 468 func Test_GetBackoffTime(t *testing.T) { 469 ms := GetBackoffTime(nil, Int(0)) 470 utils.AssertEqual(t, 0, IntValue(ms)) 471 472 backoff := map[string]interface{}{ 473 "policy": "no", 474 } 475 ms = GetBackoffTime(backoff, Int(0)) 476 utils.AssertEqual(t, 0, IntValue(ms)) 477 478 backoff["policy"] = "yes" 479 backoff["period"] = 0 480 ms = GetBackoffTime(backoff, Int(1)) 481 utils.AssertEqual(t, 0, IntValue(ms)) 482 483 Sleep(Int(1)) 484 485 backoff["period"] = 3 486 ms = GetBackoffTime(backoff, Int(1)) 487 utils.AssertEqual(t, true, IntValue(ms) <= 3) 488 } 489 490 type httpClient struct { 491 HttpClient 492 httpClient *http.Client 493 } 494 495 func newHttpClient() (*httpClient, error) { 496 client := new(httpClient) 497 err := client.Init() 498 return client, err 499 } 500 501 func (client *httpClient) Init() (_err error) { 502 return nil 503 } 504 505 func (client *httpClient) Call(request *http.Request, transport *http.Transport) (_result *http.Response, _err error) { 506 if transport != nil { 507 trans := transport.Clone() 508 client.httpClient.Transport = trans 509 } else { 510 client.httpClient.Transport = http.DefaultTransport.(*http.Transport).Clone() 511 } 512 return client.httpClient.Do(request) 513 } 514 515 func Test_DoRequest(t *testing.T) { 516 origTestHookDo := hookDo 517 defer func() { hookDo = origTestHookDo }() 518 hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) { 519 return func(req *http.Request, transport *http.Transport) (*http.Response, error) { 520 return mockResponse(200, ``, errors.New("Internal error")) 521 } 522 } 523 request := NewRequest() 524 request.Method = String("TEA TEST") 525 resp, err := DoRequest(request, nil) 526 utils.AssertNil(t, resp) 527 utils.AssertEqual(t, `net/http: invalid method "TEA TEST"`, err.Error()) 528 529 request.Method = String("") 530 request.Protocol = String("https") 531 request.Query = map[string]*string{ 532 "tea": String("test"), 533 } 534 runtimeObj["httpsProxy"] = "# #%gfdf" 535 resp, err = DoRequest(request, runtimeObj) 536 utils.AssertNil(t, resp) 537 utils.AssertContains(t, err.Error(), `invalid URL escape "%gf"`) 538 539 request.Pathname = String("?log") 540 request.Headers["tea"] = String("") 541 request.Headers["content-length"] = nil 542 runtimeObj["httpsProxy"] = "http://someuser:somepassword@ecs.aliyun.com" 543 resp, err = DoRequest(request, runtimeObj) 544 utils.AssertNil(t, resp) 545 utils.AssertEqual(t, `Internal error`, err.Error()) 546 547 request.Headers["host"] = String("tea-cn-hangzhou.aliyuncs.com:80") 548 request.Headers["user-agent"] = String("test") 549 resp, err = DoRequest(request, runtimeObj) 550 utils.AssertNil(t, resp) 551 utils.AssertEqual(t, `Internal error`, err.Error()) 552 553 runtimeObj["socks5Proxy"] = "# #%gfdf" 554 resp, err = DoRequest(request, runtimeObj) 555 utils.AssertNil(t, resp) 556 utils.AssertContains(t, err.Error(), ` invalid URL escape "%gf"`) 557 558 hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) { 559 return func(req *http.Request, transport *http.Transport) (*http.Response, error) { 560 return mockResponse(200, ``, nil) 561 } 562 } 563 runtimeObj["socks5Proxy"] = "socks5://someuser:somepassword@ecs.aliyun.com" 564 runtimeObj["localAddr"] = "127.0.0.1" 565 resp, err = DoRequest(request, runtimeObj) 566 utils.AssertNil(t, err) 567 utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"])) 568 569 runtimeObj["key"] = "private rsa key" 570 runtimeObj["cert"] = "private certification" 571 runtimeObj["ca"] = "private ca" 572 runtimeObj["ignoreSSL"] = true 573 resp, err = DoRequest(request, runtimeObj) 574 utils.AssertNil(t, err) 575 utils.AssertNotNil(t, resp) 576 577 // update the host is to restart a client 578 request.Headers["host"] = String("a.com") 579 runtimeObj["ignoreSSL"] = false 580 resp, err = DoRequest(request, runtimeObj) 581 utils.AssertNotNil(t, err) 582 utils.AssertEqual(t, "tls: failed to find any PEM data in certificate input", err.Error()) 583 utils.AssertNil(t, resp) 584 585 // update the host is to restart a client 586 request.Headers["host"] = String("b.com") 587 runtimeObj["key"] = key 588 runtimeObj["cert"] = cert 589 runtimeObj["ca"] = "private ca" 590 _, err = DoRequest(request, runtimeObj) 591 utils.AssertNotNil(t, err) 592 utils.AssertEqual(t, "Failed to parse root certificate", err.Error()) 593 594 // update the host is to restart a client 595 request.Headers["host"] = String("c.com") 596 runtimeObj["ca"] = ca 597 resp, err = DoRequest(request, runtimeObj) 598 utils.AssertNil(t, err) 599 utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"])) 600 601 request.Protocol = String("HTTP") 602 runtimeObj["ignoreSSL"] = false 603 resp, err = DoRequest(request, runtimeObj) 604 utils.AssertNil(t, err) 605 utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"])) 606 607 hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) { 608 return func(req *http.Request, transport *http.Transport) (*http.Response, error) { 609 utils.AssertEqual(t, "tea-cn-hangzhou.aliyuncs.com:1080", req.Host) 610 return mockResponse(200, ``, errors.New("Internal error")) 611 } 612 } 613 request.Pathname = String("/log") 614 request.Protocol = String("http") 615 request.Port = Int(1080) 616 request.Headers["host"] = String("tea-cn-hangzhou.aliyuncs.com") 617 resp, err = DoRequest(request, runtimeObj) 618 utils.AssertNil(t, resp) 619 utils.AssertEqual(t, `Internal error`, err.Error()) 620 621 httpClient, err := newHttpClient() 622 utils.AssertNil(t, err) 623 runtimeObj["httpClient"] = httpClient 624 resp, err = DoRequest(request, runtimeObj) 625 utils.AssertNil(t, resp) 626 utils.AssertEqual(t, `Internal error`, err.Error()) 627 } 628 629 func Test_DoRequestWithConcurrent(t *testing.T) { 630 origTestHookDo := hookDo 631 defer func() { hookDo = origTestHookDo }() 632 hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) { 633 return func(req *http.Request, transport *http.Transport) (*http.Response, error) { 634 return mockResponse(200, ``, nil) 635 } 636 } 637 var wg sync.WaitGroup 638 for i := 0; i < 50; i++ { 639 wg.Add(1) 640 go func(readTimeout int) { 641 runtime := map[string]interface{}{ 642 "readTimeout": readTimeout, 643 } 644 for j := 0; j < 50; j++ { 645 wg.Add(1) 646 go func() { 647 request := NewRequest() 648 resp, err := DoRequest(request, runtime) 649 utils.AssertNil(t, err) 650 utils.AssertNotNil(t, resp) 651 wg.Done() 652 }() 653 } 654 wg.Done() 655 }(i) 656 } 657 wg.Wait() 658 } 659 660 func Test_getHttpProxy(t *testing.T) { 661 originHttpProxy := os.Getenv("HTTP_PROXY") 662 originHttpsProxy := os.Getenv("HTTPS_PROXY") 663 originhttpproxy := os.Getenv("http_proxy") 664 originhttpsproxy := os.Getenv("https_proxy") 665 originNoProxy := os.Getenv("NO_PROXY") 666 originnoproxy := os.Getenv("no_proxy") 667 defer func() { 668 os.Setenv("HTTP_PROXY", originHttpProxy) 669 os.Setenv("HTTPS_PROXY", originHttpsProxy) 670 os.Setenv("http_proxy", originhttpproxy) 671 os.Setenv("https_proxy", originhttpsproxy) 672 os.Setenv("NO_PROXY", originNoProxy) 673 os.Setenv("no_proxy", originnoproxy) 674 }() 675 runtime := &RuntimeObject{ 676 NoProxy: String("www.aliyun.com"), 677 } 678 proxy, err := getHttpProxy("http", "www.aliyun.com", runtime) 679 utils.AssertNil(t, proxy) 680 utils.AssertNil(t, err) 681 682 runtime.NoProxy = nil 683 os.Setenv("no_proxy", "tea") 684 os.Setenv("http_proxy", "tea.aliyun.com") 685 proxy, err = getHttpProxy("http", "www.aliyun.com", runtime) 686 utils.AssertEqual(t, "tea.aliyun.com", proxy.Path) 687 utils.AssertNil(t, err) 688 689 os.Setenv("NO_PROXY", "tea") 690 os.Setenv("HTTP_PROXY", "tea1.aliyun.com") 691 proxy, err = getHttpProxy("http", "www.aliyun.com", runtime) 692 utils.AssertEqual(t, "tea1.aliyun.com", proxy.Path) 693 utils.AssertNil(t, err) 694 695 runtime.HttpProxy = String("tea2.aliyun.com") 696 proxy, err = getHttpProxy("http", "www.aliyun.com", runtime) 697 utils.AssertEqual(t, "tea2.aliyun.com", proxy.Path) 698 utils.AssertNil(t, err) 699 700 os.Setenv("no_proxy", "tea") 701 os.Setenv("https_proxy", "tea.aliyun.com") 702 proxy, err = getHttpProxy("https", "www.aliyun.com", runtime) 703 utils.AssertEqual(t, "tea.aliyun.com", proxy.Path) 704 utils.AssertNil(t, err) 705 706 os.Setenv("NO_PROXY", "tea") 707 os.Setenv("HTTPS_PROXY", "tea1.aliyun.com") 708 proxy, err = getHttpProxy("https", "www.aliyun.com", runtime) 709 utils.AssertEqual(t, "tea1.aliyun.com", proxy.Path) 710 utils.AssertNil(t, err) 711 } 712 713 func Test_SetDialContext(t *testing.T) { 714 runtime := &RuntimeObject{} 715 dialcontext := setDialContext(runtime) 716 ctx, cancelFunc := context.WithTimeout(context.Background(), 1*time.Second) 717 utils.AssertNotNil(t, cancelFunc) 718 c, err := dialcontext(ctx, "127.0.0.1", "127.0.0.2") 719 utils.AssertNil(t, c) 720 utils.AssertEqual(t, "dial 127.0.0.1: unknown network 127.0.0.1", err.Error()) 721 722 runtime.LocalAddr = String("127.0.0.1") 723 c, err = dialcontext(ctx, "127.0.0.1", "127.0.0.2") 724 utils.AssertNil(t, c) 725 utils.AssertEqual(t, "dial 127.0.0.1: unknown network 127.0.0.1", err.Error()) 726 } 727 728 func Test_hookdo(t *testing.T) { 729 fn := func(req *http.Request, transport *http.Transport) (*http.Response, error) { 730 return nil, errors.New("hookdo") 731 } 732 result := hookDo(fn) 733 resp, err := result(nil, nil) 734 utils.AssertNil(t, resp) 735 utils.AssertEqual(t, "hookdo", err.Error()) 736 } 737 738 func Test_ToReader(t *testing.T) { 739 str := "abc" 740 reader := ToReader(String(str)) 741 byt, err := ioutil.ReadAll(reader) 742 utils.AssertNil(t, err) 743 utils.AssertEqual(t, "abc", string(byt)) 744 745 read := strings.NewReader("bcd") 746 reader = ToReader(read) 747 byt, err = ioutil.ReadAll(reader) 748 utils.AssertNil(t, err) 749 utils.AssertEqual(t, "bcd", string(byt)) 750 751 byts := []byte("cdf") 752 reader = ToReader(byts) 753 byt, err = ioutil.ReadAll(reader) 754 utils.AssertNil(t, err) 755 utils.AssertEqual(t, "cdf", string(byt)) 756 757 num := 10 758 defer func() { 759 err := recover() 760 utils.AssertEqual(t, "Invalid Body. Please set a valid Body.", err.(string)) 761 }() 762 reader = ToReader(num) 763 byt, err = ioutil.ReadAll(reader) 764 utils.AssertNil(t, err) 765 utils.AssertEqual(t, "", string(byt)) 766 } 767 768 func Test_ToString(t *testing.T) { 769 str := ToString(10) 770 utils.AssertEqual(t, "10", str) 771 772 str = ToString("10") 773 utils.AssertEqual(t, "10", str) 774 } 775 776 func Test_Validate(t *testing.T) { 777 num := 3 778 config := &validateTest{ 779 Num1: &num, 780 } 781 err := Validate(config) 782 utils.AssertNil(t, err) 783 784 err = Validate(new(validateTest)) 785 utils.AssertEqual(t, err.Error(), "num1 should be setted") 786 787 var tmp *validateTest 788 err = Validate(tmp) 789 utils.AssertNil(t, err) 790 791 err = Validate(nil) 792 utils.AssertNil(t, err) 793 } 794 795 func Test_Recover(t *testing.T) { 796 err := Recover(nil) 797 utils.AssertNil(t, err) 798 defer func() { 799 if r := Recover(recover()); r != nil { 800 utils.AssertEqual(t, "test", r.Error()) 801 } 802 }() 803 panic("test") 804 } 805 806 func Test_validate(t *testing.T) { 807 var test *validateTest 808 err := validate(reflect.ValueOf(test)) 809 utils.AssertNil(t, err) 810 811 num := 3 812 str0, str1 := "abc", "abcddd" 813 val := &validateTest{ 814 Num1: &num, 815 Num2: &num, 816 Str: &str0, 817 } 818 819 err = validate(reflect.ValueOf(val)) 820 utils.AssertNil(t, err) 821 822 val.Str = &str1 823 err = validate(reflect.ValueOf(val)) 824 utils.AssertEqual(t, "The length of Str is 6 which is more than 4", err.Error()) 825 826 val.Num1 = nil 827 err = validate(reflect.ValueOf(val)) 828 utils.AssertEqual(t, "num1 should be setted", err.Error()) 829 830 val.Name1 = String("最大长度") 831 err = validate(reflect.ValueOf(val)) 832 utils.AssertEqual(t, "num1 should be setted", err.Error()) 833 834 val.Num1 = &num 835 val.Str = &str0 836 val.List = []*string{&str0} 837 err = validate(reflect.ValueOf(val)) 838 utils.AssertEqual(t, "The length of List is 1 which is less than 2", err.Error()) 839 840 val.List = []*string{&str0, &str1} 841 err = validate(reflect.ValueOf(val)) 842 utils.AssertEqual(t, "The length of List is 6 which is more than 4", err.Error()) 843 844 val.List = []*string{&str0, &str0} 845 err = validate(reflect.ValueOf(val)) 846 utils.AssertNil(t, err) 847 848 val.MaxItems = &errMaxItems{ 849 NumMax: []*int{&num}, 850 } 851 err = validate(reflect.ValueOf(val)) 852 utils.AssertEqual(t, `strconv.Atoi: parsing "a": invalid syntax`, err.Error()) 853 854 val.MaxItems = nil 855 val.MinItems = &errMinItems{ 856 NumMin: []*int{&num}, 857 } 858 err = validate(reflect.ValueOf(val)) 859 utils.AssertEqual(t, `strconv.Atoi: parsing "a": invalid syntax`, err.Error()) 860 861 val.MinItems = nil 862 val.List = []*string{&str0, &str0, &str0, &str0} 863 err = validate(reflect.ValueOf(val)) 864 utils.AssertEqual(t, "The length of List is 4 which is more than 3", err.Error()) 865 866 str2 := "test" 867 val.Str = &str2 868 err = validate(reflect.ValueOf(val)) 869 utils.AssertEqual(t, "test is not matched [a-d]*", err.Error()) 870 871 val.Str = &str0 872 val.List = []*string{&str0} 873 val.MaxLength = &errMaxLength{ 874 Num: &num, 875 } 876 err = validate(reflect.ValueOf(val)) 877 utils.AssertEqual(t, `strconv.Atoi: parsing "a": invalid syntax`, err.Error()) 878 879 val.List = nil 880 val.MaxLength = nil 881 val.MinLength = &errMinLength{ 882 Num: &num, 883 } 884 err = validate(reflect.ValueOf(val)) 885 utils.AssertEqual(t, `strconv.Atoi: parsing "a": invalid syntax`, err.Error()) 886 887 val.Name2 = String("tea") 888 val.MinLength = nil 889 val.Maximum = &errMaximum{ 890 Num: &num, 891 } 892 err = validate(reflect.ValueOf(val)) 893 utils.AssertEqual(t, `strconv.ParseFloat: parsing "a": invalid syntax`, err.Error()) 894 895 val.Maximum = nil 896 val.Minimum = &errMinimum{ 897 Num: &num, 898 } 899 err = validate(reflect.ValueOf(val)) 900 utils.AssertEqual(t, `strconv.ParseFloat: parsing "a": invalid syntax`, err.Error()) 901 902 val.Minimum = nil 903 val.Num2 = Int(10) 904 err = validate(reflect.ValueOf(val)) 905 utils.AssertEqual(t, `The size of Num2 is 10.000000 which is greater than 6.000000`, err.Error()) 906 907 val.Num2 = nil 908 val.Name1 = String("maxLengthTouch") 909 err = validate(reflect.ValueOf(val)) 910 utils.AssertEqual(t, `The length of Name1 is 14 which is more than 4`, err.Error()) 911 912 val.Name1 = nil 913 val.Name2 = String("") 914 err = validate(reflect.ValueOf(val)) 915 utils.AssertEqual(t, `The length of Name2 is 0 which is less than 2`, err.Error()) 916 917 val.Name2 = String("tea") 918 val.Num1 = Int(0) 919 err = validate(reflect.ValueOf(val)) 920 utils.AssertEqual(t, `The size of Num1 is 0.000000 which is less than 2.000000`, err.Error()) 921 } 922 923 func Test_Prettify(t *testing.T) { 924 prettifyTest := &PrettifyTest{ 925 name: "prettify", 926 Nums8: []int8{0, 1, 2, 4}, 927 Unum8: []uint8{0}, 928 Value: "ok", 929 Mapvalue: map[string]string{"key": "ccp", "value": "ok"}, 930 } 931 str := Prettify(prettifyTest) 932 utils.AssertContains(t, str, "Nums8") 933 934 str = Prettify(nil) 935 utils.AssertEqual(t, str, "null") 936 } 937 938 func Test_TransInt32AndInt(t *testing.T) { 939 a := ToInt(Int32(10)) 940 utils.AssertEqual(t, IntValue(a), 10) 941 942 b := ToInt32(a) 943 utils.AssertEqual(t, Int32Value(b), int32(10)) 944 }