github.com/alibabacloud-go/tea@v1.3.10/dara/core_test.go (about) 1 package dara 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 "retryOptions": &RetryOptions{ 34 Retryable: true, 35 RetryCondition: []*RetryCondition{ 36 {MaxAttempts: 3, Exception: []string{"AErr"}, ErrorCode: []string{"A1Err"}}, 37 }, 38 }, 39 } 40 41 var key = `-----BEGIN RSA PRIVATE KEY----- 42 MIIBPAIBAAJBAN5I1VCLYr2IlTLrFpwUGcnwl8yi6V8Mdw+myxfusNgEWiH/FQ4T 43 AZsIveiLOz9Gcc8m2mZSxst2qGII00scpiECAwEAAQJBAJZEhnA8yjN28eXKJy68 44 J/LsQrKEL1+h/ZsHFqTHJ6XfiA0CXjbjPsa4jEbpyilMTSgUyoKdJ512ioeco2n6 45 xUECIQD/JUHaKSuxz55t3efKdppqfopb92mJ2NuPJgrJI70OCwIhAN8HZ0bzr/4a 46 DLvYCDUKvOj3GzsV1dtBwWuHBaZEafQDAiEAtTnrel//7z5/U55ow4BW0gmrkQM9 47 bXIhEZ59zryZzl0CIQDFmBqRCu9eshecCP7kd3n88IjopSTOV4iUypBfyXcRnwIg 48 eXNxUx+BCu2We36+c0deE2+vizL1s6f5XhE6l4bqtiM= 49 -----END RSA PRIVATE KEY-----` 50 51 var cert = `-----BEGIN CERTIFICATE----- 52 MIIBvDCCAWYCCQDKjNYQxar0mjANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQGEwJh 53 czEMMAoGA1UECAwDYXNmMQwwCgYDVQQHDANzYWQxCzAJBgNVBAoMAnNkMQ0wCwYD 54 VQQLDARxd2VyMQswCQYDVQQDDAJzZjERMA8GCSqGSIb3DQEJARYCd2UwHhcNMjAx 55 MDE5MDI0MDMwWhcNMzAxMDE3MDI0MDMwWjBlMQswCQYDVQQGEwJhczEMMAoGA1UE 56 CAwDYXNmMQwwCgYDVQQHDANzYWQxCzAJBgNVBAoMAnNkMQ0wCwYDVQQLDARxd2Vy 57 MQswCQYDVQQDDAJzZjERMA8GCSqGSIb3DQEJARYCd2UwXDANBgkqhkiG9w0BAQEF 58 AANLADBIAkEA3kjVUItivYiVMusWnBQZyfCXzKLpXwx3D6bLF+6w2ARaIf8VDhMB 59 mwi96Is7P0ZxzybaZlLGy3aoYgjTSxymIQIDAQABMA0GCSqGSIb3DQEBCwUAA0EA 60 ZjePopbFugNK0US1MM48V1S2petIsEcxbZBEk/wGqIzrY4RCFKMtbtPSgTDUl3D9 61 XePemktG22a54ItVJ5FpcQ== 62 -----END CERTIFICATE-----` 63 64 var ca = `-----BEGIN CERTIFICATE----- 65 MIIBuDCCAWICCQCLw4OWpjlJCDANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJm 66 ZDEMMAoGA1UECAwDYXNkMQswCQYDVQQHDAJxcjEKMAgGA1UECgwBZjEMMAoGA1UE 67 CwwDc2RhMQswCQYDVQQDDAJmZDESMBAGCSqGSIb3DQEJARYDYXNkMB4XDTIwMTAx 68 OTAyNDQwNFoXDTIzMDgwOTAyNDQwNFowYzELMAkGA1UEBhMCZmQxDDAKBgNVBAgM 69 A2FzZDELMAkGA1UEBwwCcXIxCjAIBgNVBAoMAWYxDDAKBgNVBAsMA3NkYTELMAkG 70 A1UEAwwCZmQxEjAQBgkqhkiG9w0BCQEWA2FzZDBcMA0GCSqGSIb3DQEBAQUAA0sA 71 MEgCQQCxXZTl5IO61Lqd0fBBOSy7ER1gsdA0LkvflP5HEaQygjecLGfrAtD/DWu0 72 /sxCcBVnQRoP9Yp0ijHJwgXvBnrNAgMBAAEwDQYJKoZIhvcNAQELBQADQQBJF+/4 73 DEMilhlFY+o9mqCygFVxuvHtQVhpPS938H2h7/P6pXN65jK2Y5hHefZEELq9ulQe 74 91iBwaQ4e9racCgP 75 -----END CERTIFICATE-----` 76 77 type test struct { 78 Key string `json:"key,omitempty"` 79 Body []byte `json:"body,omitempty"` 80 } 81 82 type PrettifyTest struct { 83 name string 84 Strs []string 85 Nums8 []int8 86 Unum8 []uint8 87 Value string 88 Mapvalue map[string]string 89 } 90 91 type validateTest struct { 92 Num1 *int `json:"num1,omitempty" require:"true" minimum:"2"` 93 Num2 *int `json:"num2,omitempty" maximum:"6"` 94 Name1 *string `json:"name1,omitempty" maxLength:"4"` 95 Name2 *string `json:"name2,omitempty" minLength:"2"` 96 Str *string `json:"str,omitempty" pattern:"[a-d]*" maxLength:"4"` 97 MaxLength *errMaxLength `json:"MaxLength,omitempty"` 98 MinLength *errMinLength `json:"MinLength,omitempty"` 99 Maximum *errMaximum `json:"Maximum,omitempty"` 100 Minimum *errMinimum `json:"Minimum,omitempty"` 101 MaxItems *errMaxItems `json:"MaxItems,omitempty"` 102 MinItems *errMinItems `json:"MinItems,omitempty"` 103 List []*string `json:"list,omitempty" pattern:"[a-d]*" minItems:"2" maxItems:"3" maxLength:"4"` 104 } 105 106 type errMaxLength struct { 107 Num *int `json:"num" maxLength:"a"` 108 } 109 110 type errMinLength struct { 111 Num *int `json:"num" minLength:"a"` 112 } 113 114 type errMaximum struct { 115 Num *int `json:"num" maximum:"a"` 116 } 117 118 type errMinimum struct { 119 Num *int `json:"num" minimum:"a"` 120 } 121 122 type errMaxItems struct { 123 NumMax []*int `json:"num" maxItems:"a"` 124 } 125 126 type errMinItems struct { 127 NumMin []*int `json:"num" minItems:"a"` 128 } 129 130 type Progresstest struct { 131 } 132 133 func (progress *Progresstest) ProgressChanged(event *utils.ProgressEvent) { 134 } 135 136 func mockResponse(statusCode int, content string, mockerr error) (res *http.Response, err error) { 137 status := strconv.Itoa(statusCode) 138 res = &http.Response{ 139 Proto: "HTTP/1.1", 140 ProtoMajor: 1, 141 Header: map[string][]string{"TEA": []string{"test"}}, 142 StatusCode: statusCode, 143 Status: status + " " + http.StatusText(statusCode), 144 } 145 res.Body = ioutil.NopCloser(bytes.NewReader([]byte(content))) 146 err = mockerr 147 return 148 } 149 150 func TestCastError(t *testing.T) { 151 err := NewCastError(String("cast error")) 152 utils.AssertEqual(t, "cast error", err.Error()) 153 } 154 155 func TestRequest(t *testing.T) { 156 request := NewRequest() 157 utils.AssertNotNil(t, request) 158 } 159 160 func TestResponse(t *testing.T) { 161 httpresponse := &http.Response{ 162 Body: ioutil.NopCloser(strings.NewReader("response")), 163 } 164 response := NewResponse(httpresponse) 165 utils.AssertNotNil(t, response) 166 167 body, err := response.ReadBody() 168 utils.AssertEqual(t, "response", string(body)) 169 utils.AssertNil(t, err) 170 } 171 172 func TestConvert(t *testing.T) { 173 in := map[string]interface{}{ 174 "key": "value", 175 "body": []byte("test"), 176 } 177 out := new(test) 178 err := Convert(in, &out) 179 utils.AssertNil(t, err) 180 utils.AssertEqual(t, "value", out.Key) 181 utils.AssertEqual(t, "test", string(out.Body)) 182 } 183 184 func TestConvertType(t *testing.T) { 185 in := map[string]interface{}{ 186 "key": 123, 187 "body": []byte("test"), 188 } 189 out := new(test) 190 err := Convert(in, &out) 191 utils.AssertNil(t, err) 192 utils.AssertEqual(t, "123", out.Key) 193 utils.AssertEqual(t, "test", string(out.Body)) 194 } 195 196 func TestRuntimeObject(t *testing.T) { 197 runtimeobject := NewRuntimeObject(nil) 198 utils.AssertNil(t, runtimeobject.IgnoreSSL) 199 200 runtimeobject = NewRuntimeObject(runtimeObj) 201 utils.AssertEqual(t, false, BoolValue(runtimeobject.IgnoreSSL)) 202 203 utils.AssertEqual(t, true, runtimeobject.RetryOptions.Retryable) 204 205 utils.AssertEqual(t, 1, len(runtimeobject.RetryOptions.RetryCondition)) 206 } 207 208 func TestSDKError(t *testing.T) { 209 err := NewSDKError(map[string]interface{}{ 210 "code": "code", 211 "statusCode": 404, 212 "message": "message", 213 "data": map[string]interface{}{ 214 "httpCode": "404", 215 "requestId": "dfadfa32cgfdcasd4313", 216 "hostId": "github.com/alibabacloud/tea", 217 "recommend": "https://中文?q=a.b&product=c&requestId=123", 218 }, 219 "description": "description", 220 "accessDeniedDetail": map[string]interface{}{ 221 "AuthAction": "ram:ListUsers", 222 "AuthPrincipalType": "SubUser", 223 "PolicyType": "ResourceGroupLevelIdentityBassdPolicy", 224 "NoPermissionType": "ImplicitDeny", 225 "UserId": 123, 226 }, 227 }) 228 utils.AssertNotNil(t, err) 229 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()) 230 231 err.SetErrMsg("test") 232 utils.AssertEqual(t, "test", err.Error()) 233 utils.AssertEqual(t, 404, *err.StatusCode) 234 utils.AssertEqual(t, "description", *err.Description) 235 utils.AssertEqual(t, "ImplicitDeny", err.AccessDeniedDetail["NoPermissionType"]) 236 utils.AssertEqual(t, 123, err.AccessDeniedDetail["UserId"]) 237 238 err = NewSDKError(map[string]interface{}{ 239 "statusCode": "404", 240 "data": map[string]interface{}{ 241 "statusCode": 500, 242 }, 243 }) 244 utils.AssertNotNil(t, err) 245 utils.AssertEqual(t, 404, *err.StatusCode) 246 247 err = NewSDKError(map[string]interface{}{ 248 "data": map[string]interface{}{ 249 "statusCode": 500, 250 }, 251 }) 252 utils.AssertNotNil(t, err) 253 utils.AssertEqual(t, 500, *err.StatusCode) 254 255 err = NewSDKError(map[string]interface{}{ 256 "data": map[string]interface{}{ 257 "statusCode": Int(500), 258 }, 259 }) 260 utils.AssertNotNil(t, err) 261 utils.AssertEqual(t, 500, *err.StatusCode) 262 263 err = NewSDKError(map[string]interface{}{ 264 "data": map[string]interface{}{ 265 "statusCode": "500", 266 }, 267 }) 268 utils.AssertNotNil(t, err) 269 utils.AssertEqual(t, 500, *err.StatusCode) 270 271 err = NewSDKError(map[string]interface{}{ 272 "code": "code", 273 "message": "message", 274 "data": map[string]interface{}{ 275 "requestId": "dfadfa32cgfdcasd4313", 276 }, 277 }) 278 utils.AssertNotNil(t, err) 279 utils.AssertNil(t, err.StatusCode) 280 281 err = NewSDKError(map[string]interface{}{ 282 "code": "code", 283 "message": "message", 284 "data": "string data", 285 }) 286 utils.AssertNotNil(t, err) 287 utils.AssertNotNil(t, err.Data) 288 utils.AssertNil(t, err.StatusCode) 289 } 290 291 func TestSDKErrorCode404(t *testing.T) { 292 err := NewSDKError(map[string]interface{}{ 293 "statusCode": 404, 294 "code": "NOTFOUND", 295 "message": "message", 296 }) 297 utils.AssertNotNil(t, err) 298 utils.AssertEqual(t, "SDKError:\n StatusCode: 404\n Code: NOTFOUND\n Message: message\n Data: \n", err.Error()) 299 } 300 301 func TestToObject(t *testing.T) { 302 str := "{sdsfdsd:" 303 result := ToObject(str) 304 utils.AssertNil(t, result) 305 306 input := map[string]string{ 307 "name": "test", 308 } 309 result = ToObject(input) 310 utils.AssertEqual(t, "test", result["name"].(string)) 311 } 312 313 func TestAllowRetry(t *testing.T) { 314 allow := AllowRetry(nil, Int(0)) 315 utils.AssertEqual(t, true, BoolValue(allow)) 316 317 allow = AllowRetry(nil, Int(1)) 318 utils.AssertEqual(t, false, BoolValue(allow)) 319 320 input := map[string]interface{}{ 321 "retryable": false, 322 "maxAttempts": 2, 323 } 324 allow = AllowRetry(input, Int(1)) 325 utils.AssertEqual(t, false, BoolValue(allow)) 326 327 input["retryable"] = true 328 allow = AllowRetry(input, Int(3)) 329 utils.AssertEqual(t, false, BoolValue(allow)) 330 331 input["retryable"] = true 332 allow = AllowRetry(input, Int(1)) 333 utils.AssertEqual(t, true, BoolValue(allow)) 334 } 335 336 func TestMerge(t *testing.T) { 337 in := map[string]*string{ 338 "tea": String("test"), 339 } 340 valid := map[string]interface{}{ 341 "valid": "test", 342 } 343 invalidStr := "sdfdg" 344 result := Merge(in, valid, invalidStr) 345 utils.AssertEqual(t, "test", StringValue(result["tea"])) 346 utils.AssertEqual(t, "test", StringValue(result["valid"])) 347 348 result = Merge(nil) 349 utils.AssertEqual(t, map[string]*string{}, result) 350 } 351 352 type Test struct { 353 Msg *string `json:"Msg,omitempty"` 354 Cast *CastError `json:"Cast,omitempty"` 355 ListPtr []*string `json:"ListPtr,omitempty"` 356 List []string `json:"List,omitempty"` 357 CastList []CastError `json:"CastList,omitempty"` 358 CastListPtr []*CastError `json:"CastListPtr,omitempty"` 359 Reader io.Reader 360 Inter interface{} 361 } 362 363 func TestToMap(t *testing.T) { 364 inStr := map[string]string{ 365 "tea": "test", 366 "test": "test2", 367 } 368 result := ToMap(inStr) 369 utils.AssertEqual(t, "test", result["tea"]) 370 utils.AssertEqual(t, "test2", result["test"]) 371 372 inInt := map[string]int{ 373 "tea": 12, 374 "test": 13, 375 } 376 result = ToMap(inInt) 377 utils.AssertEqual(t, 12, result["tea"]) 378 utils.AssertEqual(t, 13, result["test"]) 379 380 in := map[string]*string{ 381 "tea": String("test"), 382 "nil": nil, 383 } 384 result = ToMap(in) 385 utils.AssertEqual(t, "test", result["tea"]) 386 utils.AssertNil(t, result["nil"]) 387 388 validMap := map[string]interface{}{ 389 "valid": "test", 390 } 391 result = ToMap(validMap) 392 utils.AssertEqual(t, "test", result["valid"]) 393 394 valid := &Test{ 395 Msg: String("tea"), 396 Cast: &CastError{ 397 Message: String("message"), 398 }, 399 ListPtr: StringSlice([]string{"test", ""}), 400 List: []string{"list"}, 401 CastListPtr: []*CastError{ 402 &CastError{ 403 Message: String("CastListPtr"), 404 }, 405 nil, 406 }, 407 CastList: []CastError{ 408 CastError{ 409 Message: String("CastList"), 410 }, 411 }, 412 Reader: strings.NewReader(""), 413 Inter: 10, 414 } 415 result = ToMap(valid) 416 utils.AssertEqual(t, "tea", result["Msg"]) 417 utils.AssertNil(t, result["Reader"]) 418 utils.AssertEqual(t, map[string]interface{}{"Message": "message"}, result["Cast"]) 419 utils.AssertEqual(t, []interface{}{"test", ""}, result["ListPtr"]) 420 utils.AssertEqual(t, []interface{}{"list"}, result["List"]) 421 utils.AssertEqual(t, []interface{}{map[string]interface{}{"Message": "CastListPtr"}}, result["CastListPtr"]) 422 utils.AssertEqual(t, []interface{}{map[string]interface{}{"Message": "CastList"}}, result["CastList"]) 423 424 valid1 := &Test{ 425 Msg: String("tea"), 426 } 427 result = ToMap(valid1) 428 utils.AssertEqual(t, "tea", result["Msg"]) 429 430 validStr := String(`{"test":"ok"}`) 431 result = ToMap(validStr) 432 utils.AssertEqual(t, "ok", result["test"]) 433 434 validStr1 := String(`{"test":"ok","num":1}`) 435 result = ToMap(validStr1) 436 utils.AssertEqual(t, "ok", result["test"]) 437 438 result = ToMap([]byte(StringValue(validStr))) 439 utils.AssertEqual(t, "ok", result["test"]) 440 441 result = ToMap([]byte(StringValue(validStr1))) 442 utils.AssertEqual(t, "ok", result["test"]) 443 444 invalidStr := "sdfdg" 445 result = ToMap(invalidStr) 446 utils.AssertEqual(t, map[string]interface{}{}, result) 447 448 result = ToMap(10) 449 utils.AssertEqual(t, map[string]interface{}{}, result) 450 451 result = ToMap(nil) 452 utils.AssertNil(t, result) 453 } 454 455 func Test_Retryable(t *testing.T) { 456 ifRetry := Retryable(nil) 457 utils.AssertEqual(t, false, BoolValue(ifRetry)) 458 459 err := errors.New("tea") 460 ifRetry = Retryable(err) 461 utils.AssertEqual(t, true, BoolValue(ifRetry)) 462 463 errmsg := map[string]interface{}{ 464 "code": "err", 465 } 466 err = NewSDKError(errmsg) 467 ifRetry = Retryable(err) 468 utils.AssertEqual(t, false, BoolValue(ifRetry)) 469 470 errmsg["statusCode"] = 400 471 err = NewSDKError(errmsg) 472 ifRetry = Retryable(err) 473 utils.AssertEqual(t, false, BoolValue(ifRetry)) 474 475 errmsg["statusCode"] = "400" 476 err = NewSDKError(errmsg) 477 ifRetry = Retryable(err) 478 utils.AssertEqual(t, false, BoolValue(ifRetry)) 479 480 errmsg["statusCode"] = 500 481 err = NewSDKError(errmsg) 482 ifRetry = Retryable(err) 483 utils.AssertEqual(t, true, BoolValue(ifRetry)) 484 485 errmsg["statusCode"] = "500" 486 err = NewSDKError(errmsg) 487 ifRetry = Retryable(err) 488 utils.AssertEqual(t, true, BoolValue(ifRetry)) 489 490 errmsg["statusCode"] = "test" 491 err = NewSDKError(errmsg) 492 ifRetry = Retryable(err) 493 utils.AssertEqual(t, false, BoolValue(ifRetry)) 494 } 495 496 func Test_GetBackoffTime(t *testing.T) { 497 ms := GetBackoffTime(nil, Int(0)) 498 utils.AssertEqual(t, 0, IntValue(ms)) 499 500 backoff := map[string]interface{}{ 501 "policy": "no", 502 } 503 ms = GetBackoffTime(backoff, Int(0)) 504 utils.AssertEqual(t, 0, IntValue(ms)) 505 506 backoff["policy"] = "yes" 507 backoff["period"] = 0 508 ms = GetBackoffTime(backoff, Int(1)) 509 utils.AssertEqual(t, 0, IntValue(ms)) 510 511 Sleep(1) 512 513 backoff["period"] = 3 514 ms = GetBackoffTime(backoff, Int(1)) 515 utils.AssertEqual(t, true, IntValue(ms) <= 3) 516 } 517 518 type httpClient struct { 519 HttpClient 520 httpClient *http.Client 521 } 522 523 func newHttpClient() (*httpClient, error) { 524 client := new(httpClient) 525 err := client.Init() 526 return client, err 527 } 528 529 func (client *httpClient) Init() (_err error) { 530 return nil 531 } 532 533 func (client *httpClient) Call(request *http.Request, transport *http.Transport) (_result *http.Response, _err error) { 534 if transport != nil { 535 trans := transport.Clone() 536 client.httpClient.Transport = trans 537 } else { 538 client.httpClient.Transport = http.DefaultTransport.(*http.Transport).Clone() 539 } 540 return client.httpClient.Do(request) 541 } 542 543 func Test_DoRequest(t *testing.T) { 544 origTestHookDo := hookDo 545 defer func() { hookDo = origTestHookDo }() 546 hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) { 547 return func(req *http.Request, transport *http.Transport) (*http.Response, error) { 548 return mockResponse(200, ``, errors.New("Internal error")) 549 } 550 } 551 request := NewRequest() 552 request.Method = String("TEA TEST") 553 resp, err := DoRequest(request, nil) 554 utils.AssertNil(t, resp) 555 utils.AssertEqual(t, `net/http: invalid method "TEA TEST"`, err.Error()) 556 557 request.Method = String("") 558 request.Protocol = String("https") 559 request.Query = map[string]*string{ 560 "tea": String("test"), 561 } 562 runtimeObj["httpsProxy"] = "# #%gfdf" 563 resp, err = DoRequest(request, NewRuntimeObject(runtimeObj)) 564 utils.AssertNil(t, resp) 565 utils.AssertContains(t, err.Error(), `invalid URL escape "%gf"`) 566 567 request.Pathname = String("?log") 568 request.Headers["tea"] = String("") 569 request.Headers["content-length"] = nil 570 runtimeObj["httpsProxy"] = "http://someuser:somepassword@ecs.aliyun.com" 571 resp, err = DoRequest(request, NewRuntimeObject(runtimeObj)) 572 utils.AssertNil(t, resp) 573 utils.AssertEqual(t, `Internal error`, err.Error()) 574 575 request.Headers["host"] = String("tea-cn-hangzhou.aliyuncs.com:80") 576 request.Headers["user-agent"] = String("test") 577 resp, err = DoRequest(request, NewRuntimeObject(runtimeObj)) 578 utils.AssertNil(t, resp) 579 utils.AssertEqual(t, `Internal error`, err.Error()) 580 581 runtimeObj["socks5Proxy"] = "# #%gfdf" 582 resp, err = DoRequest(request, NewRuntimeObject(runtimeObj)) 583 utils.AssertNil(t, resp) 584 utils.AssertContains(t, err.Error(), ` invalid URL escape "%gf"`) 585 586 hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) { 587 return func(req *http.Request, transport *http.Transport) (*http.Response, error) { 588 return mockResponse(200, ``, nil) 589 } 590 } 591 runtimeObj["socks5Proxy"] = "socks5://someuser:somepassword@ecs.aliyun.com" 592 runtimeObj["localAddr"] = "127.0.0.1" 593 resp, err = DoRequest(request, NewRuntimeObject(runtimeObj)) 594 utils.AssertNil(t, err) 595 utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"])) 596 597 runtimeObj["key"] = "private rsa key" 598 runtimeObj["cert"] = "private certification" 599 runtimeObj["ca"] = "private ca" 600 runtimeObj["ignoreSSL"] = true 601 resp, err = DoRequest(request, NewRuntimeObject(runtimeObj)) 602 utils.AssertNil(t, err) 603 utils.AssertNotNil(t, resp) 604 605 // update the host is to restart a client 606 request.Headers["host"] = String("a.com") 607 runtimeObj["ignoreSSL"] = false 608 resp, err = DoRequest(request, NewRuntimeObject(runtimeObj)) 609 utils.AssertNotNil(t, err) 610 utils.AssertEqual(t, "tls: failed to find any PEM data in certificate input", err.Error()) 611 utils.AssertNil(t, resp) 612 613 // update the host is to restart a client 614 request.Headers["host"] = String("b.com") 615 runtimeObj["key"] = key 616 runtimeObj["cert"] = cert 617 runtimeObj["ca"] = "private ca" 618 _, err = DoRequest(request, NewRuntimeObject(runtimeObj)) 619 utils.AssertNotNil(t, err) 620 utils.AssertEqual(t, "Failed to parse root certificate", err.Error()) 621 622 // update the host is to restart a client 623 request.Headers["host"] = String("c.com") 624 runtimeObj["ca"] = ca 625 resp, err = DoRequest(request, NewRuntimeObject(runtimeObj)) 626 utils.AssertNil(t, err) 627 utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"])) 628 629 request.Protocol = String("HTTP") 630 runtimeObj["ignoreSSL"] = false 631 resp, err = DoRequest(request, NewRuntimeObject(runtimeObj)) 632 utils.AssertNil(t, err) 633 utils.AssertEqual(t, "test", StringValue(resp.Headers["tea"])) 634 635 hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) { 636 return func(req *http.Request, transport *http.Transport) (*http.Response, error) { 637 utils.AssertEqual(t, "tea-cn-hangzhou.aliyuncs.com:1080", req.Host) 638 return mockResponse(200, ``, errors.New("Internal error")) 639 } 640 } 641 request.Pathname = String("/log") 642 request.Protocol = String("http") 643 request.Port = Int(1080) 644 request.Headers["host"] = String("tea-cn-hangzhou.aliyuncs.com") 645 resp, err = DoRequest(request, NewRuntimeObject(runtimeObj)) 646 utils.AssertNil(t, resp) 647 utils.AssertEqual(t, `Internal error`, err.Error()) 648 649 httpClient, err := newHttpClient() 650 utils.AssertNil(t, err) 651 runtimeObj["httpClient"] = httpClient 652 resp, err = DoRequest(request, NewRuntimeObject(runtimeObj)) 653 utils.AssertNil(t, resp) 654 utils.AssertEqual(t, `Internal error`, err.Error()) 655 } 656 657 func Test_DoRequestWithContextCancellation(t *testing.T) { 658 origTestHookDo := hookDo 659 defer func() { hookDo = origTestHookDo }() 660 661 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond) 662 defer cancel() 663 664 hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) { 665 return func(req *http.Request, transport *http.Transport) (*http.Response, error) { 666 select { 667 case <-time.After(2 * time.Second): 668 return &http.Response{StatusCode: 200, Header: http.Header{}, Body: http.NoBody}, nil 669 case <-ctx.Done(): 670 return nil, ctx.Err() 671 } 672 } 673 } 674 675 request := &Request{ 676 Method: String("GET"), 677 Protocol: String("http"), 678 Headers: map[string]*string{"host": String("ecs.cn-hangzhou.aliyuncs.com")}, 679 } 680 681 runtimeObject := &RuntimeObject{} 682 683 resp, err := DoRequestWithCtx(ctx, request, runtimeObject) 684 685 utils.AssertNil(t, resp) 686 if err == nil { 687 t.Fatal("Expected an error due to context timeout, got nil") 688 } 689 utils.AssertContains(t, err.Error(), "context deadline exceeded") 690 } 691 692 func Test_DoRequestWithConcurrent(t *testing.T) { 693 origTestHookDo := hookDo 694 defer func() { hookDo = origTestHookDo }() 695 hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) { 696 return func(req *http.Request, transport *http.Transport) (*http.Response, error) { 697 return mockResponse(200, ``, nil) 698 } 699 } 700 var wg sync.WaitGroup 701 for i := 0; i < 50; i++ { 702 wg.Add(1) 703 go func(readTimeout int) { 704 runtime := NewRuntimeObject(map[string]interface{}{ 705 "readTimeout": readTimeout, 706 }) 707 for j := 0; j < 50; j++ { 708 wg.Add(1) 709 go func() { 710 request := NewRequest() 711 resp, err := DoRequest(request, runtime) 712 utils.AssertNil(t, err) 713 utils.AssertNotNil(t, resp) 714 wg.Done() 715 }() 716 } 717 wg.Done() 718 }(i) 719 } 720 wg.Wait() 721 } 722 723 func Test_DoRequestWithConcurrentAndContext(t *testing.T) { 724 origTestHookDo := hookDo 725 defer func() { hookDo = origTestHookDo }() 726 hookDo = func(fn func(req *http.Request, transport *http.Transport) (*http.Response, error)) func(req *http.Request, transport *http.Transport) (*http.Response, error) { 727 return func(req *http.Request, transport *http.Transport) (*http.Response, error) { 728 time.Sleep(100 * time.Millisecond) // 模拟请求延迟 729 return mockResponse(200, ``, nil) 730 } 731 } 732 733 var wg sync.WaitGroup 734 for i := 0; i < 50; i++ { 735 wg.Add(1) 736 go func(readTimeout int) { 737 defer wg.Done() 738 739 // 每个 goroutine 有自己的上下文,设定超时控制在 500 毫秒 740 ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond) 741 defer cancel() 742 743 runtime := NewRuntimeObject(map[string]interface{}{ 744 "readTimeout": readTimeout, 745 "ctx": ctx, // 将上下文集成到运行时对象中 746 }) 747 748 for j := 0; j < 50; j++ { 749 wg.Add(1) 750 go func() { 751 defer wg.Done() 752 753 request := NewRequest() 754 resp, err := DoRequest(request, runtime) 755 756 if err != nil { 757 // 检查是否是由于上下文超时导致的错误 758 utils.AssertContains(t, err.Error(), "context deadline exceeded") 759 } else { 760 utils.AssertNil(t, err) 761 utils.AssertNotNil(t, resp) 762 } 763 }() 764 } 765 }(i) 766 } 767 wg.Wait() 768 } 769 770 func Test_getHttpProxy(t *testing.T) { 771 originHttpProxy := os.Getenv("HTTP_PROXY") 772 originHttpsProxy := os.Getenv("HTTPS_PROXY") 773 originhttpproxy := os.Getenv("http_proxy") 774 originhttpsproxy := os.Getenv("https_proxy") 775 originNoProxy := os.Getenv("NO_PROXY") 776 originnoproxy := os.Getenv("no_proxy") 777 defer func() { 778 os.Setenv("HTTP_PROXY", originHttpProxy) 779 os.Setenv("HTTPS_PROXY", originHttpsProxy) 780 os.Setenv("http_proxy", originhttpproxy) 781 os.Setenv("https_proxy", originhttpsproxy) 782 os.Setenv("NO_PROXY", originNoProxy) 783 os.Setenv("no_proxy", originnoproxy) 784 }() 785 runtime := &RuntimeObject{ 786 NoProxy: String("www.aliyun.com"), 787 } 788 proxy, err := getHttpProxy("http", "www.aliyun.com", runtime) 789 utils.AssertNil(t, proxy) 790 utils.AssertNil(t, err) 791 792 runtime.NoProxy = nil 793 os.Setenv("no_proxy", "tea") 794 os.Setenv("http_proxy", "tea.aliyun.com") 795 proxy, err = getHttpProxy("http", "www.aliyun.com", runtime) 796 utils.AssertEqual(t, "tea.aliyun.com", proxy.Path) 797 utils.AssertNil(t, err) 798 799 os.Setenv("NO_PROXY", "tea") 800 os.Setenv("HTTP_PROXY", "tea1.aliyun.com") 801 proxy, err = getHttpProxy("http", "www.aliyun.com", runtime) 802 utils.AssertEqual(t, "tea1.aliyun.com", proxy.Path) 803 utils.AssertNil(t, err) 804 805 runtime.HttpProxy = String("tea2.aliyun.com") 806 proxy, err = getHttpProxy("http", "www.aliyun.com", runtime) 807 utils.AssertEqual(t, "tea2.aliyun.com", proxy.Path) 808 utils.AssertNil(t, err) 809 810 os.Setenv("no_proxy", "tea") 811 os.Setenv("https_proxy", "tea.aliyun.com") 812 proxy, err = getHttpProxy("https", "www.aliyun.com", runtime) 813 utils.AssertEqual(t, "tea.aliyun.com", proxy.Path) 814 utils.AssertNil(t, err) 815 816 os.Setenv("NO_PROXY", "tea") 817 os.Setenv("HTTPS_PROXY", "tea1.aliyun.com") 818 proxy, err = getHttpProxy("https", "www.aliyun.com", runtime) 819 utils.AssertEqual(t, "tea1.aliyun.com", proxy.Path) 820 utils.AssertNil(t, err) 821 } 822 823 func Test_SetDialContext(t *testing.T) { 824 runtime := &RuntimeObject{} 825 dialcontext := setDialContext(runtime) 826 ctx, cancelFunc := context.WithTimeout(context.Background(), 1*time.Second) 827 utils.AssertNotNil(t, cancelFunc) 828 c, err := dialcontext(ctx, "127.0.0.1", "127.0.0.2") 829 utils.AssertNil(t, c) 830 utils.AssertEqual(t, "dial 127.0.0.1: unknown network 127.0.0.1", err.Error()) 831 832 runtime.LocalAddr = String("127.0.0.1") 833 c, err = dialcontext(ctx, "127.0.0.1", "127.0.0.2") 834 utils.AssertNil(t, c) 835 utils.AssertEqual(t, "dial 127.0.0.1: unknown network 127.0.0.1", err.Error()) 836 } 837 838 func Test_hookdo(t *testing.T) { 839 fn := func(req *http.Request, transport *http.Transport) (*http.Response, error) { 840 return nil, errors.New("hookdo") 841 } 842 result := hookDo(fn) 843 resp, err := result(nil, nil) 844 utils.AssertNil(t, resp) 845 utils.AssertEqual(t, "hookdo", err.Error()) 846 } 847 848 func Test_ToReader(t *testing.T) { 849 str := "abc" 850 reader := ToReader(String(str)) 851 byt, err := ioutil.ReadAll(reader) 852 utils.AssertNil(t, err) 853 utils.AssertEqual(t, "abc", string(byt)) 854 855 read := strings.NewReader("bcd") 856 reader = ToReader(read) 857 byt, err = ioutil.ReadAll(reader) 858 utils.AssertNil(t, err) 859 utils.AssertEqual(t, "bcd", string(byt)) 860 861 byts := []byte("cdf") 862 reader = ToReader(byts) 863 byt, err = ioutil.ReadAll(reader) 864 utils.AssertNil(t, err) 865 utils.AssertEqual(t, "cdf", string(byt)) 866 867 num := 10 868 defer func() { 869 err := recover() 870 utils.AssertEqual(t, "Invalid Body. Please set a valid Body.", err.(string)) 871 }() 872 reader = ToReader(num) 873 byt, err = ioutil.ReadAll(reader) 874 utils.AssertNil(t, err) 875 utils.AssertEqual(t, "", string(byt)) 876 } 877 878 func Test_ToWriter(t *testing.T) { 879 str := "abc" 880 writer := ToWriter(str).(*bytes.Buffer) 881 utils.AssertEqual(t, "abc", writer.String()) 882 883 strPtr := new(string) 884 *strPtr = "def" 885 writer = ToWriter(strPtr).(*bytes.Buffer) 886 utils.AssertEqual(t, "def", writer.String()) 887 888 bytesData := []byte("ghi") 889 writer = ToWriter(bytesData).(*bytes.Buffer) 890 utils.AssertEqual(t, "ghi", writer.String()) 891 892 buffer := new(bytes.Buffer) 893 writer = ToWriter(buffer).(*bytes.Buffer) 894 utils.AssertEqual(t, buffer, writer) 895 896 fileWriter := ToWriter(os.Stdout) 897 utils.AssertEqual(t, os.Stdout, fileWriter) 898 899 var buf bytes.Buffer 900 writer2 := ToWriter(&buf) 901 writer2.Write([]byte("test")) 902 utils.AssertEqual(t, "test", buf.String()) 903 904 // Test a non-writer to trigger panic 905 defer func() { 906 if r := recover(); r != nil { 907 utils.AssertEqual(t, "Invalid Writer. Please provide a valid Writer.", r) 908 } 909 }() 910 num := 10 911 ToWriter(num) // This should cause a panic 912 } 913 914 func Test_ToString(t *testing.T) { 915 str := ToString(10) 916 utils.AssertEqual(t, "10", str) 917 918 str = ToString("10") 919 utils.AssertEqual(t, "10", str) 920 } 921 922 func Test_Validate(t *testing.T) { 923 var tmp *validateTest 924 num := 3 925 config := &validateTest{ 926 Num1: &num, 927 } 928 err := Validate(config) 929 utils.AssertNil(t, err) 930 931 err = Validate(new(validateTest)) 932 utils.AssertEqual(t, err.Error(), "num1 should be setted") 933 err = Validate(tmp) 934 utils.AssertNil(t, err) 935 936 err = Validate(nil) 937 utils.AssertNil(t, err) 938 } 939 940 func Test_Recover(t *testing.T) { 941 err := Recover(nil) 942 utils.AssertNil(t, err) 943 defer func() { 944 if r := Recover(recover()); r != nil { 945 utils.AssertEqual(t, "test", r.Error()) 946 } 947 }() 948 panic("test") 949 } 950 951 func Test_validate(t *testing.T) { 952 var test *validateTest 953 err := validate(reflect.ValueOf(test)) 954 utils.AssertNil(t, err) 955 956 num := 3 957 str0, str1 := "abc", "abcddd" 958 val := &validateTest{ 959 Num1: &num, 960 Num2: &num, 961 Str: &str0, 962 } 963 964 err = validate(reflect.ValueOf(val)) 965 utils.AssertNil(t, err) 966 967 val.Str = &str1 968 err = validate(reflect.ValueOf(val)) 969 utils.AssertEqual(t, "The length of Str is 6 which is more than 4", err.Error()) 970 971 val.Num1 = nil 972 err = validate(reflect.ValueOf(val)) 973 utils.AssertEqual(t, "num1 should be setted", err.Error()) 974 975 val.Name1 = String("最大长度") 976 err = validate(reflect.ValueOf(val)) 977 utils.AssertEqual(t, "num1 should be setted", err.Error()) 978 979 val.Num1 = &num 980 val.Str = &str0 981 val.List = []*string{&str0} 982 err = validate(reflect.ValueOf(val)) 983 utils.AssertEqual(t, "The length of List is 1 which is less than 2", err.Error()) 984 985 val.List = []*string{&str0, &str1} 986 err = validate(reflect.ValueOf(val)) 987 utils.AssertEqual(t, "The length of List is 6 which is more than 4", err.Error()) 988 989 val.List = []*string{&str0, &str0} 990 err = validate(reflect.ValueOf(val)) 991 utils.AssertNil(t, err) 992 993 val.MaxItems = &errMaxItems{ 994 NumMax: []*int{&num}, 995 } 996 err = validate(reflect.ValueOf(val)) 997 utils.AssertEqual(t, `strconv.Atoi: parsing "a": invalid syntax`, err.Error()) 998 999 val.MaxItems = nil 1000 val.MinItems = &errMinItems{ 1001 NumMin: []*int{&num}, 1002 } 1003 err = validate(reflect.ValueOf(val)) 1004 utils.AssertEqual(t, `strconv.Atoi: parsing "a": invalid syntax`, err.Error()) 1005 1006 val.MinItems = nil 1007 val.List = []*string{&str0, &str0, &str0, &str0} 1008 err = validate(reflect.ValueOf(val)) 1009 utils.AssertEqual(t, "The length of List is 4 which is more than 3", err.Error()) 1010 1011 str2 := "test" 1012 val.Str = &str2 1013 err = validate(reflect.ValueOf(val)) 1014 utils.AssertEqual(t, "test is not matched [a-d]*", err.Error()) 1015 1016 val.Str = &str0 1017 val.List = []*string{&str0} 1018 val.MaxLength = &errMaxLength{ 1019 Num: &num, 1020 } 1021 err = validate(reflect.ValueOf(val)) 1022 utils.AssertEqual(t, `strconv.Atoi: parsing "a": invalid syntax`, err.Error()) 1023 1024 val.List = nil 1025 val.MaxLength = nil 1026 val.MinLength = &errMinLength{ 1027 Num: &num, 1028 } 1029 err = validate(reflect.ValueOf(val)) 1030 utils.AssertEqual(t, `strconv.Atoi: parsing "a": invalid syntax`, err.Error()) 1031 1032 val.Name2 = String("tea") 1033 val.MinLength = nil 1034 val.Maximum = &errMaximum{ 1035 Num: &num, 1036 } 1037 err = validate(reflect.ValueOf(val)) 1038 utils.AssertEqual(t, `strconv.ParseFloat: parsing "a": invalid syntax`, err.Error()) 1039 1040 val.Maximum = nil 1041 val.Minimum = &errMinimum{ 1042 Num: &num, 1043 } 1044 err = validate(reflect.ValueOf(val)) 1045 utils.AssertEqual(t, `strconv.ParseFloat: parsing "a": invalid syntax`, err.Error()) 1046 1047 val.Minimum = nil 1048 val.Num2 = Int(10) 1049 err = validate(reflect.ValueOf(val)) 1050 utils.AssertEqual(t, `The size of Num2 is 10.000000 which is greater than 6.000000`, err.Error()) 1051 1052 val.Num2 = nil 1053 val.Name1 = String("maxLengthTouch") 1054 err = validate(reflect.ValueOf(val)) 1055 utils.AssertEqual(t, `The length of Name1 is 14 which is more than 4`, err.Error()) 1056 1057 val.Name1 = nil 1058 val.Name2 = String("") 1059 err = validate(reflect.ValueOf(val)) 1060 utils.AssertEqual(t, `The length of Name2 is 0 which is less than 2`, err.Error()) 1061 1062 val.Name2 = String("tea") 1063 val.Num1 = Int(0) 1064 err = validate(reflect.ValueOf(val)) 1065 utils.AssertEqual(t, `The size of Num1 is 0.000000 which is less than 2.000000`, err.Error()) 1066 } 1067 1068 func Test_Prettify(t *testing.T) { 1069 prettifyTest := &PrettifyTest{ 1070 name: "prettify", 1071 Nums8: []int8{0, 1, 2, 4}, 1072 Unum8: []uint8{0}, 1073 Value: "ok", 1074 Mapvalue: map[string]string{"key": "ccp", "value": "ok"}, 1075 } 1076 str := Prettify(prettifyTest) 1077 utils.AssertContains(t, str, "Nums8") 1078 1079 str = Prettify(nil) 1080 utils.AssertEqual(t, str, "null") 1081 } 1082 1083 func Test_TransInt32AndInt(t *testing.T) { 1084 a := ToInt(Int32(10)) 1085 utils.AssertEqual(t, IntValue(a), 10) 1086 1087 b := ToInt32(a) 1088 utils.AssertEqual(t, Int32Value(b), int32(10)) 1089 } 1090 1091 func Test_Default(t *testing.T) { 1092 a := ToInt(Int32(10)) 1093 utils.AssertEqual(t, IntValue(a), 10) 1094 1095 b := ToInt32(a) 1096 utils.AssertEqual(t, Int32Value(b), int32(10)) 1097 1098 // Testing Default with nil values 1099 if result := Default(nil, "default"); result != "default" { 1100 t.Errorf("expected 'default', got '%v'", result) 1101 } 1102 1103 // Testing Default with zero values 1104 if result := Default("", "default"); result != "default" { 1105 t.Errorf("expected 'default', got '%v'", result) 1106 } 1107 1108 if result := Default(0, 42); result != 42 { 1109 t.Errorf("expected 42, got %v", result) 1110 } 1111 1112 if result := Default(false, true); result != true { 1113 t.Errorf("expected true, got %v", result) 1114 } 1115 1116 // Testing Default with non-zero values 1117 if result := Default("value", "default"); result != "value" { 1118 t.Errorf("expected 'value', got '%v'", result) 1119 } 1120 1121 if result := Default([]int{1, 2, 3}, []int{}); !reflect.DeepEqual(result, []int{1, 2, 3}) { 1122 t.Errorf("expected [1 2 3], got '%v'", result) 1123 } 1124 } 1125 1126 func TestToBytes(t *testing.T) { 1127 tests := []struct { 1128 input string 1129 encodingType string 1130 expected []byte 1131 }{ 1132 {"Hello, World!", "utf8", []byte("Hello, World!")}, 1133 {"SGVsbG8sIFdvcmxkIQ==", "base64", []byte("Hello, World!")}, 1134 {"48656c6c6f2c20576f726c6421", "hex", []byte("Hello, World!")}, 1135 {"invalid base64", "base64", nil}, 1136 {"invalid hex", "hex", nil}, 1137 {"unsupported", "unsupported", nil}, 1138 } 1139 1140 for _, tt := range tests { 1141 result := ToBytes(tt.input, tt.encodingType) 1142 1143 if !reflect.DeepEqual(result, tt.expected) { 1144 t.Errorf("ToBytes(%q, %q) = %v, want %v", 1145 tt.input, tt.encodingType, result, tt.expected) 1146 } 1147 } 1148 } 1149 1150 func TestForceInt(t *testing.T) { 1151 tests := []struct { 1152 input interface{} 1153 expected int 1154 }{ 1155 {int(42), 42}, 1156 {int(-10), -10}, 1157 {nil, 0}, // nil should return zero value for int 1158 } 1159 1160 for _, test := range tests { 1161 result := ForceInt(test.input) 1162 if result != test.expected { 1163 t.Errorf("ForceInt(%v) = %v; want %v", test.input, result, test.expected) 1164 } 1165 } 1166 } 1167 1168 func TestForceBoolean(t *testing.T) { 1169 tests := []struct { 1170 input interface{} 1171 expected bool 1172 }{ 1173 {true, true}, 1174 {false, false}, 1175 {nil, false}, // nil should return zero value for bool 1176 } 1177 1178 for _, test := range tests { 1179 result := ForceBoolean(test.input) 1180 if result != test.expected { 1181 t.Errorf("ForceBoolean(%v) = %v; want %v", test.input, result, test.expected) 1182 } 1183 } 1184 } 1185 1186 func TestForceInt32(t *testing.T) { 1187 tests := []struct { 1188 input interface{} 1189 expected int32 1190 }{ 1191 {int32(42), 42}, 1192 {int32(-10), -10}, 1193 {nil, 0}, // nil should return zero value for int32 1194 } 1195 1196 for _, test := range tests { 1197 result := ForceInt32(test.input) 1198 if result != test.expected { 1199 t.Errorf("ForceInt32(%v) = %v; want %v", test.input, result, test.expected) 1200 } 1201 } 1202 } 1203 1204 func TestForceUInt32(t *testing.T) { 1205 tests := []struct { 1206 input interface{} 1207 expected uint32 1208 }{ 1209 {uint32(100), 100}, 1210 {uint32(0), 0}, 1211 {nil, 0}, // nil should return zero value for uint32 1212 } 1213 1214 for _, test := range tests { 1215 result := ForceUInt32(test.input) 1216 if result != test.expected { 1217 t.Errorf("ForceUInt32(%v) = %v; want %v", test.input, result, test.expected) 1218 } 1219 } 1220 } 1221 1222 func TestForceInt16(t *testing.T) { 1223 tests := []struct { 1224 input interface{} 1225 expected int16 1226 }{ 1227 {int16(12345), 12345}, 1228 {int16(-543), -543}, 1229 {nil, 0}, // nil should return zero value for int16 1230 } 1231 1232 for _, test := range tests { 1233 result := ForceInt16(test.input) 1234 if result != test.expected { 1235 t.Errorf("ForceInt16(%v) = %v; want %v", test.input, result, test.expected) 1236 } 1237 } 1238 } 1239 1240 func TestForceUInt16(t *testing.T) { 1241 tests := []struct { 1242 input interface{} 1243 expected uint16 1244 }{ 1245 {uint16(65535), 65535}, 1246 {uint16(1), 1}, 1247 {nil, 0}, // nil should return zero value for uint16 1248 } 1249 1250 for _, test := range tests { 1251 result := ForceUInt16(test.input) 1252 if result != test.expected { 1253 t.Errorf("ForceUInt16(%v) = %v; want %v", test.input, result, test.expected) 1254 } 1255 } 1256 } 1257 1258 func TestForceInt8(t *testing.T) { 1259 tests := []struct { 1260 input interface{} 1261 expected int8 1262 }{ 1263 {int8(127), 127}, 1264 {int8(-128), -128}, 1265 {nil, 0}, // nil should return zero value for int8 1266 } 1267 1268 for _, test := range tests { 1269 result := ForceInt8(test.input) 1270 if result != test.expected { 1271 t.Errorf("ForceInt8(%v) = %v; want %v", test.input, result, test.expected) 1272 } 1273 } 1274 } 1275 1276 func TestForceUInt8(t *testing.T) { 1277 tests := []struct { 1278 input interface{} 1279 expected uint8 1280 }{ 1281 {uint8(255), 255}, 1282 {uint8(0), 0}, 1283 {nil, 0}, // nil should return zero value for uint8 1284 } 1285 1286 for _, test := range tests { 1287 result := ForceUInt8(test.input) 1288 if result != test.expected { 1289 t.Errorf("ForceUInt8(%v) = %v; want %v", test.input, result, test.expected) 1290 } 1291 } 1292 } 1293 1294 func TestForceFloat32(t *testing.T) { 1295 tests := []struct { 1296 input interface{} 1297 expected float32 1298 }{ 1299 {float32(3.14), 3.14}, 1300 {float32(-2.71), -2.71}, 1301 {nil, 0}, // nil should return zero value for float32 1302 } 1303 1304 for _, test := range tests { 1305 result := ForceFloat32(test.input) 1306 if result != test.expected { 1307 t.Errorf("ForceFloat32(%v) = %v; want %v", test.input, result, test.expected) 1308 } 1309 } 1310 } 1311 1312 func TestForceFloat64(t *testing.T) { 1313 tests := []struct { 1314 input interface{} 1315 expected float64 1316 }{ 1317 {float64(2.718), 2.718}, 1318 {float64(-3.14), -3.14}, 1319 {nil, 0}, // nil should return zero value for float64 1320 } 1321 1322 for _, test := range tests { 1323 result := ForceFloat64(test.input) 1324 if result != test.expected { 1325 t.Errorf("ForceFloat64(%v) = %v; want %v", test.input, result, test.expected) 1326 } 1327 } 1328 } 1329 1330 func TestForceInt64(t *testing.T) { 1331 tests := []struct { 1332 input interface{} 1333 expected int64 1334 }{ 1335 {int64(123456789), 123456789}, 1336 {int64(-987654321), -987654321}, 1337 {nil, 0}, // nil should return zero value for int64 1338 } 1339 1340 for _, test := range tests { 1341 result := ForceInt64(test.input) 1342 if result != test.expected { 1343 t.Errorf("ForceInt64(%v) = %v; want %v", test.input, result, test.expected) 1344 } 1345 } 1346 } 1347 1348 func TestForceUint64(t *testing.T) { 1349 tests := []struct { 1350 input interface{} 1351 expected uint64 1352 }{ 1353 {uint64(123456789), 123456789}, 1354 {uint64(0), 0}, 1355 {nil, 0}, // nil should return zero value for uint64 1356 } 1357 1358 for _, test := range tests { 1359 result := ForceUint64(test.input) 1360 if result != test.expected { 1361 t.Errorf("ForceUint64(%v) = %v; want %v", test.input, result, test.expected) 1362 } 1363 } 1364 }