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  }