Browse Source

Merge pull request #29 from aliyun/test

publish 0.8.1
gaort 8 years ago
parent
commit
dc8dcaff2a
44 changed files with 824 additions and 341 deletions
  1. 6 0
      ChangeLog.txt
  2. 31 0
      integration/cdn_test.go
  3. 27 20
      integration/ecs_test.go
  4. 199 0
      integration/rds_test.go
  5. 20 13
      integration/slb_test.go
  6. 4 5
      integration/utils.go
  7. 85 0
      integration/vpc_test.go
  8. 0 6
      sdk/auth/credentials/BaseCredential.go
  9. 0 5
      sdk/auth/credentials/EcsInstanceCredential.go
  10. 0 7
      sdk/auth/credentials/KeyPairCredential.go
  11. 0 9
      sdk/auth/credentials/StsAssumeRoleCredential.go
  12. 0 7
      sdk/auth/credentials/StsCredential.go
  13. 13 0
      sdk/auth/credentials/base_credential.go
  14. 15 0
      sdk/auth/credentials/rsa_key_pair_credential.go
  15. 15 0
      sdk/auth/credentials/sts_credential.go
  16. 19 0
      sdk/auth/credentials/sts_role_arn_credential.go
  17. 11 0
      sdk/auth/credentials/sts_role_name_on_ecs_credential.go
  18. 8 8
      sdk/auth/signer.go
  19. 2 2
      sdk/auth/signers/signer_ecs_instance.go
  20. 3 3
      sdk/auth/signers/signer_key_pair.go
  21. 2 2
      sdk/auth/signers/signer_sts.go
  22. 4 4
      sdk/auth/signers/signer_sts_assume_role.go
  23. 2 2
      sdk/auth/signers/signer_v2.go
  24. 58 22
      sdk/client.go
  25. 88 45
      sdk/client_test.go
  26. 1 1
      sdk/config.go
  27. 24 11
      sdk/endpoints/location_resolver.go
  28. 8 8
      sdk/endpoints/resolver.go
  29. 23 13
      sdk/errors/client_error.go
  30. 2 2
      sdk/requests/acs_reqeust.go
  31. 3 3
      sdk/requests/common_request.go
  32. 12 3
      sdk/requests/types_test.go
  33. 0 11
      sdk/responses/json_parser_test.go
  34. 7 0
      sdk/responses/response.go
  35. 3 0
      sdk/utils/utils.go
  36. 60 60
      vendor/github.com/jmespath/go-jmespath/functions.go
  37. 6 6
      vendor/github.com/jmespath/go-jmespath/interpreter_test.go
  38. 49 49
      vendor/github.com/jmespath/go-jmespath/lexer_test.go
  39. 2 2
      vendor/github.com/jmespath/go-jmespath/parser.go
  40. 1 1
      vendor/github.com/jmespath/go-jmespath/util_test.go
  41. 3 3
      vendor/github.com/stretchr/testify/mock/mock_test.go
  42. 2 2
      vendor/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/format_test.go
  43. 4 4
      vendor/github.com/stretchr/testify/vendor/github.com/pmezard/go-difflib/difflib/difflib.go
  44. 2 2
      vendor/github.com/stretchr/testify/vendor/github.com/pmezard/go-difflib/difflib/difflib_test.go

+ 6 - 0
ChangeLog.txt

@@ -1,3 +1,9 @@
+2018-01-18 Version: 0.8.2
+1. Set default timeout to 10s
+2. Make integration tests more stable
+3. Fix the problem of LocationResolver in concurrency
+4. Modifying the naming specification
+
 2018-01-18 Version: 0.8.1
 1, Update ECS go SDK to catch up with other langs.
 2, DescribeImageSupportInstanceTypes add new param Filter and ActionType

+ 31 - 0
integration/cdn_test.go

@@ -0,0 +1,31 @@
+package integration
+
+import (
+	"fmt"
+	"github.com/aliyun/alibaba-cloud-sdk-go/services/cdn"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestCdnInstance(t *testing.T) {
+
+	// init client
+	config := getConfigFromEnv()
+	cdnClient, err := cdn.NewClientWithAccessKey("cn-hangzhou", config.AccessKeyId, config.AccessKeySecret)
+	assertErrorNil(t, err, "Failed to init client")
+	fmt.Printf("Init client success\n")
+
+	// getCdnStatus
+	assertCdnStatus(t, cdnClient)
+
+}
+
+func assertCdnStatus(t *testing.T, client *cdn.Client) {
+	fmt.Print("describing cdn service status...")
+	request := cdn.CreateDescribeCdnServiceRequest()
+	response, err := client.DescribeCdnService(request)
+	assertErrorNil(t, err, "Failed to describing cdn service status")
+	assert.Equal(t, 200, response.GetHttpStatus(), response.GetHttpContentString())
+	assert.Equal(t, "PayByTraffic", response.InternetChargeType)
+	fmt.Printf("ok(%d)!\n", response.GetHttpStatus())
+}

+ 27 - 20
integration/ecs_test.go

@@ -2,21 +2,22 @@ package integration
 
 import (
 	"fmt"
+	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
 	"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
 	"github.com/stretchr/testify/assert"
+	"strconv"
+	"strings"
 	"testing"
 	"time"
-	"strings"
-	"strconv"
 )
 
 const (
 	EcsInstanceDefaultTimeout = 120
 	EcsDefaultWaitForInterval = 20
 
-	EcsInstanceStatusRunning  = "Running"
-	EcsInstanceStatusStopped  = "Stopped"
-	EcsInstanceStatusDeleted  = "Deleted"
+	EcsInstanceStatusRunning = "Running"
+	EcsInstanceStatusStopped = "Stopped"
+	EcsInstanceStatusDeleted = "Deleted"
 )
 
 // create -> start -> stop -> delete
@@ -55,7 +56,7 @@ func TestEcsInstance(t *testing.T) {
 	// wait
 	waitForEcsInstance(t, ecsClient, instanceId, EcsInstanceStatusStopped, 600)
 
-	// delete all test instance
+	//delete all test instance
 	deleteAllTestEcsInstance(t, ecsClient)
 }
 
@@ -118,29 +119,35 @@ func deleteEcsInstance(t *testing.T, client *ecs.Client, instanceId string) {
 func deleteAllTestEcsInstance(t *testing.T, client *ecs.Client) {
 	fmt.Print("list all ecs instances...")
 	request := ecs.CreateDescribeInstancesRequest()
-	request.PageSize = "10"
-	request.PageNumber = "1"
+	request.PageSize = requests.NewInteger(10)
+	request.PageNumber = requests.NewInteger(1)
 	response, err := client.DescribeInstances(request)
 	assertErrorNil(t, err, "Failed to list all ecs instances ")
 	assert.Equal(t, 200, response.GetHttpStatus(), response.GetHttpContentString())
-	fmt.Printf("success! TotalCount = %s\n", response.TotalCount)
+	fmt.Printf("success! TotalCount = %s\n", strconv.Itoa(response.TotalCount))
 
 	for _, instanceInfo := range response.Instances.Instance {
 		if strings.HasPrefix(instanceInfo.InstanceName, InstanceNamePrefix) {
-			fmt.Printf("found undeleted ecs instance(%s), status=%s, try to delete it.\n",
-				instanceInfo.Status, instanceInfo.InstanceId)
-			if instanceInfo.Status == EcsInstanceStatusRunning {
-				// stop
-				stopEcsInstance(t, client, instanceInfo.InstanceId)
-			}else if instanceInfo.Status == EcsInstanceStatusStopped {
-				// delete
-				deleteEcsInstance(t, client, instanceInfo.InstanceId)
-				// wait
-				waitForEcsInstance(t, client, instanceInfo.InstanceId, EcsInstanceStatusDeleted, 600)
+			createTime, err := strconv.ParseInt(instanceInfo.InstanceName[26:len(instanceInfo.InstanceName)], 10, 64)
+			assertErrorNil(t, err, "Parse instance create time failed: "+instanceInfo.InstanceName)
+			if (time.Now().Unix() - createTime) < (5 * 60) {
+				fmt.Printf("found undeleted ecs instance(%s) but created in 5 minutes, try to delete next time\n",instanceInfo.InstanceName)
+				return
+			}else{
+				fmt.Printf("found undeleted ecs instance(%s), status=%s, try to delete it.\n",
+					instanceInfo.Status, instanceInfo.InstanceId)
+				if instanceInfo.Status == EcsInstanceStatusRunning {
+					// stop
+					stopEcsInstance(t, client, instanceInfo.InstanceId)
+				} else if instanceInfo.Status == EcsInstanceStatusStopped {
+					// delete
+					deleteEcsInstance(t, client, instanceInfo.InstanceId)
+					// wait
+					waitForEcsInstance(t, client, instanceInfo.InstanceId, EcsInstanceStatusDeleted, 600)
+				}
 			}
 		}
 	}
-
 }
 
 func waitForEcsInstance(t *testing.T, client *ecs.Client, instanceId string, targetStatus string, timeout int) {

+ 199 - 0
integration/rds_test.go

@@ -0,0 +1,199 @@
+package integration
+
+import (
+	"fmt"
+	"github.com/aliyun/alibaba-cloud-sdk-go/services/rds"
+	"github.com/stretchr/testify/assert"
+	"strconv"
+	"strings"
+	"testing"
+	"time"
+	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
+	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
+)
+
+const (
+	RdsInstanceDefaultTimeout = 120
+	RdsDefaultWaitForInterval = 60
+
+	RdsInstanceStatusRunning = "Running"
+	RdsInstanceStatusStopped = "Stopped"
+	RdsInstanceStatusDeleted = "Deleted"
+)
+
+func TestRdsInstance(t *testing.T) {
+
+	// init client
+	testConfig := getConfigFromEnv()
+	credential := &credentials.BaseCredential{
+		AccessKeyId:     testConfig.AccessKeyId,
+		AccessKeySecret: testConfig.AccessKeySecret,
+	}
+	clientConfig := sdk.NewConfig().WithTimeout(30 * time.Second)
+	rdsClient, err := rds.NewClientWithOptions("cn-hangzhou", clientConfig, credential)
+	assertErrorNil(t, err, "Failed to init client")
+	fmt.Printf("Init client success\n")
+
+	dbInstanceId := createDBInstance(t, rdsClient)
+
+	waitForRdsInstance(t, rdsClient, dbInstanceId, RdsInstanceStatusRunning, 1200)
+
+	//createAccount(t, rdsClient, dbInstanceId)
+
+	//nodeId := getHAConfig(t, rdsClient, dbInstanceId)
+	//
+	//changeNodeToMaster(t, rdsClient, dbInstanceId, nodeId)
+	//
+	//createDataBase(t, rdsClient, dbInstanceId)
+
+	deleteDBInstance(t, rdsClient, dbInstanceId)
+
+	deleteAllTestRdsInstance(t, rdsClient)
+}
+
+func createDBInstance(t *testing.T, client *rds.Client) (rdsInstanceId string) {
+	fmt.Print("creating rds mysql instance...")
+	request := rds.CreateCreateDBInstanceRequest()
+	request.Engine = "MySQL"
+	request.EngineVersion = "5.7"
+	request.DBInstanceClass = "mysql.n1.micro.1"
+	request.DBInstanceStorage = "20"
+	request.DBInstanceNetType = "Intranet"
+	request.SecurityIPList = "0.0.0.0/0"
+	request.PayType = "Postpaid"
+	request.DBInstanceDescription = InstanceNamePrefix + strconv.FormatInt(time.Now().Unix(), 10)
+	response, err := client.CreateDBInstance(request)
+	assertErrorNil(t, err, "Failed to create rds mysql instance")
+	assert.Equal(t, 200, response.GetHttpStatus(), response.GetHttpContentString())
+	rdsInstanceId = response.DBInstanceId
+	fmt.Printf("success(%d)! dbInstanceId = %s\n", response.GetHttpStatus(), rdsInstanceId)
+	return
+}
+
+func getHAConfig(t *testing.T, client *rds.Client, instanceId string) (nodeId string) {
+	fmt.Print("get dbInstance HA nodeId...")
+	request := rds.CreateDescribeDBInstanceHAConfigRequest()
+	request.DBInstanceId = instanceId
+	response, err := client.DescribeDBInstanceHAConfig(request)
+	assertErrorNil(t, err, "Failed to get dbInstance HA nodeId")
+	assert.Equal(t, 200, response.GetHttpStatus(), response.GetHttpContentString())
+	nodeId = response.HostInstanceInfos.NodeInfo[0].NodeId
+	fmt.Printf("success(%d)! nodeId = %s\n", response.GetHttpStatus(), nodeId)
+	return
+}
+
+func changeNodeToMaster(t *testing.T, client *rds.Client, instanceId, nodeId string) {
+	fmt.Print("trying to change current instance to master...")
+	request := rds.CreateSwitchDBInstanceHARequest()
+	request.DBInstanceId = instanceId
+	request.NodeId = nodeId
+	response, err := client.SwitchDBInstanceHA(request)
+	assertErrorNil(t, err, "Failed to change current instance to master")
+	assert.Equal(t, 200, response.GetHttpStatus(), response.GetHttpContentString())
+	fmt.Printf("success(%d)!\n", response.GetHttpStatus())
+	return
+}
+
+func createAccount(t *testing.T, client *rds.Client, instanceId string) {
+	fmt.Print("creating mysql account...")
+	request := rds.CreateCreateAccountRequest()
+	request.DBInstanceId = instanceId
+	request.AccountName = "sdktest"
+	request.AccountPassword = strconv.FormatInt(time.Now().Unix(), 10)
+	response, err := client.CreateAccount(request)
+	assertErrorNil(t, err, "Failed to create mysql account")
+	assert.Equal(t, 200, response.GetHttpStatus(), response.GetHttpContentString())
+	fmt.Printf("success(%d)!\n", response.GetHttpStatus())
+	return
+}
+
+func createDataBase(t *testing.T, client *rds.Client, instanceId string) {
+	fmt.Print("creating mysql database...")
+	request := rds.CreateCreateDatabaseRequest()
+	request.DBInstanceId = instanceId
+	request.DBName = "sdktest"
+	request.CharacterSetName = "utf8"
+	response, err := client.CreateDatabase(request)
+	assertErrorNil(t, err, "Failed to create mysql database")
+	assert.Equal(t, 200, response.GetHttpStatus(), response.GetHttpContentString())
+	fmt.Printf("success(%d)!\n", response.GetHttpStatus())
+	return
+}
+
+func deleteDBInstance(t *testing.T, client *rds.Client, instanceId string) {
+	fmt.Print("deleting rds instance...")
+	request := rds.CreateDeleteDBInstanceRequest()
+	request.DBInstanceId = instanceId
+	response, err := client.DeleteDBInstance(request)
+	assertErrorNil(t, err, "Failed to delete rds instance")
+	assert.Equal(t, 200, response.GetHttpStatus(), response.GetHttpContentString())
+	fmt.Printf("success(%d)!\n", response.GetHttpStatus())
+	return
+}
+
+func waitForRdsInstance(t *testing.T, client *rds.Client, instanceId string, targetStatus string, timeout int) {
+	if timeout <= 0 {
+		timeout = RdsInstanceDefaultTimeout
+	}
+	for {
+		request := rds.CreateDescribeDBInstanceAttributeRequest()
+		request.DBInstanceId = instanceId
+		response, err := client.DescribeDBInstanceAttribute(request)
+
+		currentStatus := getSingleInstanceStatusFromDescribeDBInstanceAttributeResponse(response)
+		if targetStatus == RdsInstanceStatusDeleted {
+			if currentStatus == targetStatus {
+				fmt.Printf("delete rds instance(%s) success\n", instanceId)
+				break
+			} else {
+				assertErrorNil(t, err, "Failed to describe rds instance \n")
+			}
+		} else {
+			assertErrorNil(t, err, "Failed to describe rds instance \n")
+			if currentStatus == targetStatus {
+				fmt.Printf("rds instance(%s) status changed to %s, wait a moment\n", instanceId, targetStatus)
+				time.Sleep(RdsDefaultWaitForInterval * time.Second)
+				break
+			} else {
+				fmt.Printf("rds instance(%s) status is %s, wait for changing to %s\n", instanceId, currentStatus, targetStatus)
+			}
+		}
+
+		timeout = timeout - RdsDefaultWaitForInterval
+		if timeout <= 0 {
+			t.Errorf(fmt.Sprintf("wait for ecs instance(%s) status to %s timeout(%d)\n", instanceId, targetStatus, timeout))
+		}
+		time.Sleep(RdsDefaultWaitForInterval * time.Second)
+	}
+}
+
+func deleteAllTestRdsInstance(t *testing.T, client *rds.Client) {
+	// list all instances
+	fmt.Print("trying to list all rds test instances...")
+	listRequest := rds.CreateDescribeDBInstancesRequest()
+	listResponse, err := client.DescribeDBInstances(listRequest)
+	assertErrorNil(t, err, "Failed to list all rds instances")
+	assert.Equal(t, 200, listResponse.GetHttpStatus(), listResponse.GetHttpContentString())
+
+	fmt.Printf("found %s instances\n", strconv.Itoa(listResponse.TotalRecordCount))
+	for _, instance := range listResponse.Items.DBInstance {
+		if strings.HasPrefix(instance.DBInstanceDescription, InstanceNamePrefix) {
+			createTime, err := strconv.ParseInt(instance.DBInstanceDescription[len(InstanceNamePrefix):], 10, 64)
+			assertErrorNil(t, err, "Parse instance create time failed: "+instance.DBInstanceDescription)
+			if (time.Now().Unix() - createTime) < (5 * 60) {
+				fmt.Printf("found undeleted rds instance(%s) but created in 5 minutes, try to delete next time\n", instance.DBInstanceDescription)
+				return
+			} else {
+				fmt.Printf("found rds test instance(%s), trying to delte it\n", instance.DBInstanceId)
+				deleteDBInstance(t, client, instance.DBInstanceId)
+			}
+		}
+	}
+}
+
+func getSingleInstanceStatusFromDescribeDBInstanceAttributeResponse(response *rds.DescribeDBInstanceAttributeResponse) string {
+	if response.GetHttpStatus() == 404 || len(response.Items.DBInstanceAttribute) == 0 {
+		return RdsInstanceStatusDeleted
+	}
+	return response.Items.DBInstanceAttribute[0].DBInstanceStatus
+}

+ 20 - 13
integration/slb_test.go

@@ -2,14 +2,14 @@ package integration
 
 import (
 	"fmt"
-	"github.com/stretchr/testify/assert"
-	"testing"
-	"time"
-	"github.com/aliyun/alibaba-cloud-sdk-go/services/slb"
-	"strconv"
 	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils"
+	"github.com/aliyun/alibaba-cloud-sdk-go/services/slb"
+	"github.com/stretchr/testify/assert"
 	"net/http"
+	"strconv"
 	"strings"
+	"testing"
+	"time"
 )
 
 const (
@@ -128,18 +128,25 @@ func deleteAllTestSlbInstance(t *testing.T, client *slb.Client) {
 	response, err := client.DescribeLoadBalancers(request)
 	assertErrorNil(t, err, "Failed to list all slb instances")
 	assert.Equal(t, 200, response.GetHttpStatus(), response.GetHttpContentString())
-	fmt.Printf("success(%d)! TotalCount = %s\n", response.GetHttpStatus(), response.TotalCount)
+	fmt.Printf("success(%d)! TotalCount = %s\n", response.GetHttpStatus(), strconv.Itoa(response.TotalCount))
 
 	for _, slbInstanceInfo := range response.LoadBalancers.LoadBalancer {
 		if strings.HasPrefix(slbInstanceInfo.LoadBalancerName, InstanceNamePrefix) {
-			fmt.Printf("found undeleted slb instance(%s), status=%s, try to delete it.\n",
-				slbInstanceInfo.LoadBalancerId, slbInstanceInfo.LoadBalancerStatus)
-			if slbInstanceInfo.LoadBalancerStatus != SlbInstanceStopped {
-				// stop
-				stopSlbInstance(t, client, slbInstanceInfo.LoadBalancerId)
+			createTime, err := strconv.ParseInt(slbInstanceInfo.LoadBalancerName[len(InstanceNamePrefix):], 10, 64)
+			assertErrorNil(t, err, "Parse instance create time failed: "+slbInstanceInfo.LoadBalancerName)
+			if (time.Now().Unix() - createTime) < (5 * 60) {
+				fmt.Printf("found undeleted slb instance(%s) but created in 5 minutes, try to delete next time\n", slbInstanceInfo.LoadBalancerName)
+				return
+			} else {
+				fmt.Printf("found undeleted slb instance(%s), status=%s, try to delete it.\n",
+					slbInstanceInfo.LoadBalancerId, slbInstanceInfo.LoadBalancerStatus)
+				if slbInstanceInfo.LoadBalancerStatus != SlbInstanceStopped {
+					// stop
+					stopSlbInstance(t, client, slbInstanceInfo.LoadBalancerId)
+				}
+				// delete
+				deleteSlbInstance(t, client, slbInstanceInfo.LoadBalancerId)
 			}
-			// delete
-			deleteSlbInstance(t, client, slbInstanceInfo.LoadBalancerId)
 		}
 	}
 }

+ 4 - 5
integration/utils.go

@@ -1,12 +1,12 @@
 package integration
 
 import (
+	"fmt"
 	"os"
 	"testing"
-	"fmt"
 )
 
-const InstanceNamePrefix  = "SdkIntegrationTestInstance"
+const InstanceNamePrefix = "SdkIntegrationTestInstance"
 
 type Config struct {
 	AccessKeyId     string
@@ -29,13 +29,12 @@ func getConfigFromEnv() *Config {
 		ChildSecret:     os.Getenv("CHILD_SECRET"),
 	}
 	if config.AccessKeyId == "" {
-		return nil
+		panic("Get ACCESS_KEY_ID from environment variables failed")
 	} else {
 		return config
 	}
 }
 
-
 func getEcsDemoInstanceId() string {
 	return os.Getenv("DEMO_ECS_INSTANCE_ID")
 }
@@ -44,4 +43,4 @@ func assertErrorNil(t *testing.T, err error, message string) {
 	if err != nil {
 		fmt.Fprintf(os.Stderr, message+": %v\n", err)
 	}
-}
+}

+ 85 - 0
integration/vpc_test.go

@@ -0,0 +1,85 @@
+package integration
+
+import (
+	"fmt"
+	"github.com/aliyun/alibaba-cloud-sdk-go/services/vpc"
+	"github.com/stretchr/testify/assert"
+	"strconv"
+	"testing"
+	"time"
+)
+
+func TestVpcInstance(t *testing.T) {
+
+	// init client
+	config := getConfigFromEnv()
+	vpcClient, err := vpc.NewClientWithAccessKey("cn-hangzhou", config.AccessKeyId, config.AccessKeySecret)
+	assertErrorNil(t, err, "Failed to init client")
+	fmt.Printf("Init client success\n")
+
+	// create vpc
+	vpcId := createVpcInstance(t, vpcClient)
+
+	time.Sleep(5 * time.Second)
+
+	// create switch
+	vswitchId := createVswitchInstance(t, vpcClient, vpcId)
+
+	time.Sleep(5 * time.Second)
+
+	// delete vswitch
+	deleteVSwitchInstance(t, vpcClient, vswitchId)
+
+	// delete vpc
+	deleteVpcInstance(t, vpcClient, vpcId)
+}
+
+func createVpcInstance(t *testing.T, client *vpc.Client) (vpcId string) {
+	fmt.Print("creating vpc instance...")
+	request := vpc.CreateCreateVpcRequest()
+	request.VpcName = InstanceNamePrefix + strconv.FormatInt(time.Now().Unix(), 10)
+	request.CidrBlock = "192.168.0.0/16"
+	response, err := client.CreateVpc(request)
+	assertErrorNil(t, err, "Failed to create vpc instance")
+	assert.Equal(t, 200, response.GetHttpStatus(), response.GetHttpContentString())
+	vpcId = response.VpcId
+	fmt.Printf("success(%d)! vpcId = %s\n", response.GetHttpStatus(), vpcId)
+	return
+}
+
+func createVswitchInstance(t *testing.T, client *vpc.Client, vpcId string) (vswitchId string) {
+	fmt.Print("creating vswitch instance...")
+	request := vpc.CreateCreateVSwitchRequest()
+	request.VSwitchName = InstanceNamePrefix + strconv.FormatInt(time.Now().Unix(), 10)
+	request.VpcId = vpcId
+	request.ZoneId = "cn-hangzhou-b"
+	request.CidrBlock = "192.168.3.0/24"
+	response, err := client.CreateVSwitch(request)
+	assertErrorNil(t, err, "Failed to create vswitch instance")
+	assert.Equal(t, 200, response.GetHttpStatus(), response.GetHttpContentString())
+	vswitchId = response.VSwitchId
+	fmt.Printf("success(%d)! VSwitchId = %s\n", response.GetHttpStatus(), vpcId)
+	return
+}
+
+func deleteVSwitchInstance(t *testing.T, client *vpc.Client, vswitchId string) {
+	fmt.Printf("deleting vswitch instance(%s)...", vswitchId)
+	request := vpc.CreateDeleteVSwitchRequest()
+	request.VSwitchId = vswitchId
+	response, err := client.DeleteVSwitch(request)
+	assertErrorNil(t, err, "Failed to delete vswitch instance")
+	assert.Equal(t, 200, response.GetHttpStatus(), response.GetHttpContentString())
+	fmt.Printf("success(%d)!\n", response.GetHttpStatus())
+	return
+}
+
+func deleteVpcInstance(t *testing.T, client *vpc.Client, vpcId string) {
+	fmt.Printf("deleting vpc instance(%s)...", vpcId)
+	request := vpc.CreateDeleteVpcRequest()
+	request.VpcId = vpcId
+	response, err := client.DeleteVpc(request)
+	assertErrorNil(t, err, "Failed to delete vpc instance")
+	assert.Equal(t, 200, response.GetHttpStatus(), response.GetHttpContentString())
+	fmt.Printf("success(%d)!\n", response.GetHttpStatus())
+	return
+}

+ 0 - 6
sdk/auth/credentials/BaseCredential.go

@@ -1,6 +0,0 @@
-package credentials
-
-type BaseCredential struct {
-	AccessKeyId     string
-	AccessKeySecret string
-}

+ 0 - 5
sdk/auth/credentials/EcsInstanceCredential.go

@@ -1,5 +0,0 @@
-package credentials
-
-type EcsInstanceCredential struct {
-	RoleName string
-}

+ 0 - 7
sdk/auth/credentials/KeyPairCredential.go

@@ -1,7 +0,0 @@
-package credentials
-
-type KeyPairCredential struct {
-	PrivateKey        string
-	PublicKeyId       string
-	SessionExpiration int
-}

+ 0 - 9
sdk/auth/credentials/StsAssumeRoleCredential.go

@@ -1,9 +0,0 @@
-package credentials
-
-type StsAssumeRoleCredential struct {
-	AccessKeyId           string
-	AccessKeySecret       string
-	RoleArn               string
-	RoleSessionName       string
-	RoleSessionExpiration int
-}

+ 0 - 7
sdk/auth/credentials/StsCredential.go

@@ -1,7 +0,0 @@
-package credentials
-
-type StsCredential struct {
-	AccessKeyId       string
-	AccessKeySecret   string
-	AccessKeyStsToken string
-}

+ 13 - 0
sdk/auth/credentials/base_credential.go

@@ -0,0 +1,13 @@
+package credentials
+
+type BaseCredential struct {
+	AccessKeyId     string
+	AccessKeySecret string
+}
+
+func NewBaseCredential(accessKeyId, accessKeySecret string) *BaseCredential {
+	return &BaseCredential{
+		AccessKeyId:     accessKeyId,
+		AccessKeySecret: accessKeySecret,
+	}
+}

+ 15 - 0
sdk/auth/credentials/rsa_key_pair_credential.go

@@ -0,0 +1,15 @@
+package credentials
+
+type RsaKeyPairCredential struct {
+	PrivateKey        string
+	PublicKeyId       string
+	SessionExpiration int
+}
+
+func NewRsaKeyPairCredential(privateKey, publicKeyId string, sessionExpiration int) *RsaKeyPairCredential {
+	return &RsaKeyPairCredential{
+		PrivateKey:        privateKey,
+		PublicKeyId:       publicKeyId,
+		SessionExpiration: sessionExpiration,
+	}
+}

+ 15 - 0
sdk/auth/credentials/sts_credential.go

@@ -0,0 +1,15 @@
+package credentials
+
+type StsTokenCredential struct {
+	AccessKeyId       string
+	AccessKeySecret   string
+	AccessKeyStsToken string
+}
+
+func NewStsTokenCredential(accessKeyId, accessKeySecret, accessKeyStsToken string) *StsTokenCredential {
+	return &StsTokenCredential{
+		AccessKeyId:       accessKeyId,
+		AccessKeySecret:   accessKeySecret,
+		AccessKeyStsToken: accessKeyStsToken,
+	}
+}

+ 19 - 0
sdk/auth/credentials/sts_role_arn_credential.go

@@ -0,0 +1,19 @@
+package credentials
+
+type StsRoleArnCredential struct {
+	AccessKeyId           string
+	AccessKeySecret       string
+	RoleArn               string
+	RoleSessionName       string
+	RoleSessionExpiration int
+}
+
+func NewStsRoleArnCredential(accessKeyId, accessKeySecret, roleArn, roleSessionName string, roleSessionExpiration int) *StsRoleArnCredential {
+	return &StsRoleArnCredential{
+		AccessKeyId:           accessKeyId,
+		AccessKeySecret:       accessKeySecret,
+		RoleArn:               roleArn,
+		RoleSessionName:       roleSessionName,
+		RoleSessionExpiration: roleSessionExpiration,
+	}
+}

+ 11 - 0
sdk/auth/credentials/sts_role_name_on_ecs_credential.go

@@ -0,0 +1,11 @@
+package credentials
+
+type StsRoleNameOnEcsCredential struct {
+	RoleName string
+}
+
+func NewStsRoleNameOnEcsCredential(roleName string) *StsRoleNameOnEcsCredential {
+	return &StsRoleNameOnEcsCredential{
+		RoleName: roleName,
+	}
+}

+ 8 - 8
sdk/auth/signer.go

@@ -40,25 +40,25 @@ func NewSignerWithCredential(credential Credential, commonApi func(request *requ
 		{
 			signer, err = signers.NewSignerV1(instance)
 		}
-	case *credentials.StsCredential:
+	case *credentials.StsTokenCredential:
 		{
 			signer, err = signers.NewSignerSts(instance)
 		}
-	case *credentials.StsAssumeRoleCredential:
+	case *credentials.StsRoleArnCredential:
 		{
 			signer, err = signers.NewSignerStsAssumeRole(instance, commonApi)
 		}
-	case *credentials.KeyPairCredential:
+	case *credentials.RsaKeyPairCredential:
 		{
 			signer, err = signers.NewSignerKeyPair(instance, commonApi)
 		}
-	case *credentials.EcsInstanceCredential:
+	case *credentials.StsRoleNameOnEcsCredential:
 		{
 			signer, err = signers.NewSignereEcsInstance(instance, commonApi)
 		}
 	default:
-		message := fmt.Sprintf(errors.UnsupportedCredentialMessage, reflect.TypeOf(credential))
-		err = errors.NewClientError(errors.UnsupportedCredentialCode, message, nil)
+		message := fmt.Sprintf(errors.UnsupportedCredentialErrorMessage, reflect.TypeOf(credential))
+		err = errors.NewClientError(errors.UnsupportedCredentialErrorCode, message, nil)
 	}
 	return
 }
@@ -74,8 +74,8 @@ func Sign(request requests.AcsRequest, signer Signer, regionId string) (err erro
 			signRpcRequest(request, signer, regionId)
 		}
 	default:
-		message := fmt.Sprintf(errors.UnknownRequestTypeMessage, reflect.TypeOf(request))
-		err = errors.NewClientError(errors.UnknownRequestTypeCode, message, nil)
+		message := fmt.Sprintf(errors.UnknownRequestTypeErrorMessage, reflect.TypeOf(request))
+		err = errors.NewClientError(errors.UnknownRequestTypeErrorCode, message, nil)
 	}
 
 	return

+ 2 - 2
sdk/auth/signers/signer_ecs_instance.go

@@ -29,11 +29,11 @@ import (
 type SignerEcsInstance struct {
 	*credentialUpdater
 	sessionCredential *sessionCredential
-	credential        *credentials.EcsInstanceCredential
+	credential        *credentials.StsRoleNameOnEcsCredential
 	commonApi         func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)
 }
 
-func NewSignereEcsInstance(credential *credentials.EcsInstanceCredential, commonApi func(*requests.CommonRequest, interface{}) (response *responses.CommonResponse, err error)) (signer *SignerEcsInstance, err error) {
+func NewSignereEcsInstance(credential *credentials.StsRoleNameOnEcsCredential, commonApi func(*requests.CommonRequest, interface{}) (response *responses.CommonResponse, err error)) (signer *SignerEcsInstance, err error) {
 	signer = &SignerEcsInstance{
 		credential: credential,
 		commonApi:  commonApi,

+ 3 - 3
sdk/auth/signers/signer_key_pair.go

@@ -29,7 +29,7 @@ import (
 type SignerKeyPair struct {
 	*credentialUpdater
 	sessionCredential *SessionAkCredential
-	credential        *credentials.KeyPairCredential
+	credential        *credentials.RsaKeyPairCredential
 	commonApi         func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)
 }
 
@@ -38,7 +38,7 @@ type SessionAkCredential struct {
 	accessKeySecret string
 }
 
-func NewSignerKeyPair(credential *credentials.KeyPairCredential, commonApi func(*requests.CommonRequest, interface{}) (response *responses.CommonResponse, err error)) (signer *SignerKeyPair, err error) {
+func NewSignerKeyPair(credential *credentials.RsaKeyPairCredential, commonApi func(*requests.CommonRequest, interface{}) (response *responses.CommonResponse, err error)) (signer *SignerKeyPair, err error) {
 	signer = &SignerKeyPair{
 		credential: credential,
 		commonApi:  commonApi,
@@ -55,7 +55,7 @@ func NewSignerKeyPair(credential *credentials.KeyPairCredential, commonApi func(
 		if credential.SessionExpiration >= 900 && credential.SessionExpiration <= 3600 {
 			signer.credentialExpiration = credential.SessionExpiration
 		} else {
-			err = errors.NewClientError(errors.InvalidParamCode, "Key Pair session duration should be in the range of 15min - 1Hr", nil)
+			err = errors.NewClientError(errors.InvalidParamErrorCode, "Key Pair session duration should be in the range of 15min - 1Hr", nil)
 		}
 	} else {
 		signer.credentialExpiration = defaultDurationSeconds

+ 2 - 2
sdk/auth/signers/signer_sts.go

@@ -19,10 +19,10 @@ import (
 )
 
 type SignerSts struct {
-	credential *credentials.StsCredential
+	credential *credentials.StsTokenCredential
 }
 
-func NewSignerSts(credential *credentials.StsCredential) (*SignerSts, error) {
+func NewSignerSts(credential *credentials.StsTokenCredential) (*SignerSts, error) {
 	return &SignerSts{
 		credential: credential,
 	}, nil

+ 4 - 4
sdk/auth/signers/signer_sts_assume_role.go

@@ -35,7 +35,7 @@ type SignerStsAssumeRole struct {
 	*credentialUpdater
 	roleSessionName   string
 	sessionCredential *sessionCredential
-	credential        *credentials.StsAssumeRoleCredential
+	credential        *credentials.StsRoleArnCredential
 	commonApi         func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)
 }
 
@@ -45,7 +45,7 @@ type sessionCredential struct {
 	securityToken   string
 }
 
-func NewSignerStsAssumeRole(credential *credentials.StsAssumeRoleCredential, commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)) (signer *SignerStsAssumeRole, err error) {
+func NewSignerStsAssumeRole(credential *credentials.StsRoleArnCredential, commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)) (signer *SignerStsAssumeRole, err error) {
 	signer = &SignerStsAssumeRole{
 		credential: credential,
 		commonApi:  commonApi,
@@ -64,10 +64,10 @@ func NewSignerStsAssumeRole(credential *credentials.StsAssumeRoleCredential, com
 		signer.roleSessionName = "aliyun-go-sdk-" + strconv.FormatInt(time.Now().UnixNano()/1000, 10)
 	}
 	if credential.RoleSessionExpiration > 0 {
-		if credential.RoleSessionExpiration > 900 && credential.RoleSessionExpiration < 3600 {
+		if credential.RoleSessionExpiration >= 900 && credential.RoleSessionExpiration <= 3600 {
 			signer.credentialExpiration = credential.RoleSessionExpiration
 		} else {
-			err = errors.NewClientError(errors.InvalidParamCode, "Assume Role session duration should be in the range of 15min - 1Hr", nil)
+			err = errors.NewClientError(errors.InvalidParamErrorCode, "Assume Role session duration should be in the range of 15min - 1Hr", nil)
 		}
 	} else {
 		signer.credentialExpiration = defaultDurationSeconds

+ 2 - 2
sdk/auth/signers/signer_v2.go

@@ -19,14 +19,14 @@ import (
 )
 
 type SignerV2 struct {
-	credential *credentials.KeyPairCredential
+	credential *credentials.RsaKeyPairCredential
 }
 
 func (signer *SignerV2) GetExtraParam() map[string]string {
 	return nil
 }
 
-func NewSignerV2(credential *credentials.KeyPairCredential) (*SignerV2, error) {
+func NewSignerV2(credential *credentials.RsaKeyPairCredential) (*SignerV2, error) {
 	return &SignerV2{
 		credential: credential,
 	}, nil

+ 58 - 22
sdk/client.go

@@ -23,6 +23,8 @@ import (
 	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
 	"net"
 	"net/http"
+	"fmt"
+	"strconv"
 )
 
 // this value will be replaced while build: -ldflags="-X sdk.version=x.x.x"
@@ -92,9 +94,19 @@ func (client *Client) InitWithAccessKey(regionId, accessKeyId, accessKeySecret s
 	return client.InitWithOptions(regionId, config, credential)
 }
 
-func (client *Client) InitWithRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (err error) {
+func (client *Client) InitWithSecurityToken(regionId, accessKeyId, accessKeySecret, securityToken string) (err error) {
 	config := client.InitClientConfig()
-	credential := &credentials.StsAssumeRoleCredential{
+	credential := &credentials.StsTokenCredential{
+		AccessKeyId:       accessKeyId,
+		AccessKeySecret:   accessKeySecret,
+		AccessKeyStsToken: securityToken,
+	}
+	return client.InitWithOptions(regionId, config, credential)
+}
+
+func (client *Client) InitWithStsRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (err error) {
+	config := client.InitClientConfig()
+	credential := &credentials.StsRoleArnCredential{
 		AccessKeyId:     accessKeyId,
 		AccessKeySecret: accessKeySecret,
 		RoleArn:         roleArn,
@@ -103,9 +115,9 @@ func (client *Client) InitWithRoleArn(regionId, accessKeyId, accessKeySecret, ro
 	return client.InitWithOptions(regionId, config, credential)
 }
 
-func (client *Client) InitWithKeyPair(regionId, publicKeyId, privateKey string, sessionExpiration int) (err error) {
+func (client *Client) InitWithRsaKeyPair(regionId, publicKeyId, privateKey string, sessionExpiration int) (err error) {
 	config := client.InitClientConfig()
-	credential := &credentials.KeyPairCredential{
+	credential := &credentials.RsaKeyPairCredential{
 		PrivateKey:        privateKey,
 		PublicKeyId:       publicKeyId,
 		SessionExpiration: sessionExpiration,
@@ -113,21 +125,20 @@ func (client *Client) InitWithKeyPair(regionId, publicKeyId, privateKey string,
 	return client.InitWithOptions(regionId, config, credential)
 }
 
-func (client *Client) InitWithEcsInstance(regionId, roleName string) (err error) {
+func (client *Client) InitWithStsRoleNameOnEcs(regionId, roleName string) (err error) {
 	config := client.InitClientConfig()
-	credential := &credentials.EcsInstanceCredential{
+	credential := &credentials.StsRoleNameOnEcsCredential{
 		RoleName: roleName,
 	}
 	return client.InitWithOptions(regionId, config, credential)
 }
 
 func (client *Client) InitClientConfig() (config *Config) {
-	config = NewConfig()
 	if client.config != nil {
-		config = client.config
+		return client.config
+	}else{
+		return NewConfig()
 	}
-
-	return
 }
 
 func (client *Client) DoAction(request requests.AcsRequest, response responses.AcsResponse) (err error) {
@@ -146,12 +157,12 @@ func (client *Client) DoActionWithSigner(request requests.AcsRequest, response r
 
 	// resolve endpoint
 	resolveParam := &endpoints.ResolveParam{
-		Domain:           request.GetDomain(),
-		Product:          request.GetProduct(),
-		RegionId:         client.regionId,
-		LocationProduct:  request.GetLocationServiceCode(),
-		LocationEndpoint: request.GetLocationEndpointType(),
-		CommonApi:        client.ProcessCommonRequest,
+		Domain:               request.GetDomain(),
+		Product:              request.GetProduct(),
+		RegionId:             regionId,
+		LocationProduct:      request.GetLocationServiceCode(),
+		LocationEndpointType: request.GetLocationEndpointType(),
+		CommonApi:            client.ProcessCommonRequest,
 	}
 	endpoint, err := endpoints.Resolve(resolveParam)
 	if err != nil {
@@ -190,20 +201,21 @@ func (client *Client) DoActionWithSigner(request requests.AcsRequest, response r
 	for retryTimes := 0; retryTimes <= client.config.MaxRetryTime; retryTimes++ {
 		httpResponse, err = client.httpClient.Do(httpRequest)
 
-		// retry params
 		var timeout bool
-		var serverError bool
-
 		// receive error
 		if err != nil {
-			// if not timeout error, return
 			if timeout = isTimeout(err); !timeout {
+				// if not timeout error, return
+				return
+			} else if retryTimes >= client.config.MaxRetryTime {
+				// timeout but reached the max retry times, return
+				timeoutErrorMsg := fmt.Sprintf(errors.TimeoutErrorMessage, strconv.Itoa(retryTimes + 1), strconv.Itoa(retryTimes + 1))
+				err = errors.NewClientError(errors.TimeoutErrorCode, timeoutErrorMsg, err)
 				return
 			}
 		}
-		serverError = isServerError(httpResponse)
 		//  if status code >= 500 or timeout, will trigger retry
-		if client.config.AutoRetry && (timeout || serverError) {
+		if client.config.AutoRetry && (timeout || isServerError(httpResponse)) {
 			continue
 		}
 		break
@@ -251,6 +263,30 @@ func NewClientWithAccessKey(regionId, accessKeyId, accessKeySecret string) (clie
 	return
 }
 
+func NewClientWithStsToken(regionId, accessKeyId, accessKeySecret, accessKeyStsToken string) (client *Client, err error) {
+	client = &Client{}
+	err = client.InitWithSecurityToken(regionId, accessKeyId, accessKeySecret, accessKeyStsToken)
+	return
+}
+
+func NewClientWithRsaKeyPair(regionId string, publicKeyId, privateKey string, sessionExpiration int) (client *Client, err error) {
+	client = &Client{}
+	err = client.InitWithRsaKeyPair(regionId, publicKeyId, privateKey, sessionExpiration)
+	return
+}
+
+func NewClientWithStsRoleNameOnEcs(regionId string, roleName string) (client *Client, err error) {
+	client = &Client{}
+	err = client.InitWithStsRoleNameOnEcs(regionId, roleName)
+	return
+}
+
+func NewClientWithStsRoleArn(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (client *Client, err error) {
+	client = &Client{}
+	err = client.InitWithStsRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName)
+	return
+}
+
 func (client *Client) ProcessCommonRequest(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
 	request.TransToAcsRequest()
 	response = responses.NewCommonResponse()

+ 88 - 45
sdk/client_test.go

@@ -28,7 +28,7 @@ import (
 	"testing"
 )
 
-var client, clientKeyPair, clientEcs, clientRoleArn *Client
+var client, clientKeyPair, clientEcs, clientRoleArn, clientSts *Client
 
 type TestConfig struct {
 	AccessKeyId     string
@@ -36,6 +36,9 @@ type TestConfig struct {
 	PublicKeyId     string
 	PrivateKey      string
 	RoleArn         string
+	StsToken        string
+	StsAk           string
+	StsSecret       string
 	ChildAK         string
 	ChildSecret     string
 }
@@ -81,8 +84,11 @@ func getConfigFromEnv() *TestConfig {
 		RoleArn:         os.Getenv("ROLE_ARN"),
 		ChildAK:         os.Getenv("CHILD_AK"),
 		ChildSecret:     os.Getenv("CHILD_SECRET"),
+		StsToken:        os.Getenv("STS_TOKEN"),
+		StsAk:           os.Getenv("STS_AK"),
+		StsSecret:       os.Getenv("STS_SECRET"),
 	}
-	if config.AccessKeyId == "" {
+	if config.AccessKeyId == "" || os.Getenv("ENV_TYPE") != "CI" {
 		return nil
 	} else {
 		return config
@@ -95,11 +101,19 @@ func testSetup() {
 		testConfig = getConfigFromFile()
 	}
 
-	clientConfig := NewConfig().WithHttpTransport(&http.Transport{
-		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
-	})
-
 	var err error
+
+	clientConfig := NewConfig().
+		WithEnableAsync(true).
+		WithGoRoutinePoolSize(5).
+		WithMaxTaskQueueSize(1000).
+		WithHttpTransport(&http.Transport{
+			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+		})
+		//}).
+		//WithMaxRetryTime(15).
+		//WithTimeout(10)
+
 	credential := &credentials.BaseCredential{
 		AccessKeyId:     testConfig.AccessKeyId,
 		AccessKeySecret: testConfig.AccessKeySecret,
@@ -108,18 +122,30 @@ func testSetup() {
 	if err != nil {
 		panic(err)
 	}
-	//err = clientKeyPair.InitWithKeyPair("cn-hangzhou", testConfig.PublicKeyId, testConfig.PrivateKey, 3600)
-	//if err != nil {
-	//	panic(err)
-	//}
-	//err = clientEcs.InitWithEcsInstance("cn-hangzhou", "conan")
-	//if err != nil {
-	//	panic(err)
-	//}
-	//err = clientRoleArn.InitWithRoleArn("cn-hangzhou", testConfig.ChildAK, testConfig.ChildSecret, testConfig.RoleArn, "clientTest")
-	//if err != nil {
-	//	panic(err)
-	//}
+
+	rsaKeypairCredential := credentials.NewRsaKeyPairCredential(testConfig.PrivateKey, testConfig.PublicKeyId, 3600)
+	clientKeyPair, err = NewClientWithOptions("cn-hangzhou", clientConfig, rsaKeypairCredential)
+	if err != nil {
+		panic(err)
+	}
+
+	roleNameOnEcsCredential := credentials.NewStsRoleNameOnEcsCredential("conan")
+	clientEcs, err = NewClientWithOptions("cn-hangzhou", clientConfig, roleNameOnEcsCredential)
+	if err != nil {
+		panic(err)
+	}
+
+	stsRoleArnCredential := credentials.NewStsRoleArnCredential(testConfig.ChildAK, testConfig.ChildSecret, testConfig.RoleArn, "clientTest", 3600)
+	clientRoleArn, err = NewClientWithOptions("cn-hangzhou", clientConfig, stsRoleArnCredential)
+	if err != nil {
+		panic(err)
+	}
+
+	stsCredential := credentials.NewStsTokenCredential(testConfig.StsAk, testConfig.StsSecret, testConfig.StsToken)
+	clientSts, err = NewClientWithOptions("cn-hangzhou", clientConfig, stsCredential)
+	if err != nil {
+		panic(err)
+	}
 }
 
 func testTearDown() {
@@ -297,7 +323,7 @@ func getFtTestRpcRequest() (request *requests.RpcRequest) {
 func getFtTestRpcRequestForEndpointLocation() (request *requests.RpcRequest) {
 	request = &requests.RpcRequest{}
 	request.InitWithApiInfo("Ft", "2016-01-01", "TestRpcApi", "ft", "openAPI")
-	request.RegionId = "cn-hangzhou"
+	request.RegionId = "ft-cn-hangzhou"
 	request.QueryParams["QueryParam"] = "QueryParamValue"
 	return
 }
@@ -418,21 +444,21 @@ func TestRpcGetForLocationCache(t *testing.T) {
 	assert.Equal(t, "QueryParamValue", responseBean.Params["QueryParam"])
 }
 
-//func TestRpcGetForKeyPair(t *testing.T) {
-//	request := getFtTestRpcRequest()
-//	request.Method = requests.GET
-//
-//	response := &responses.BaseResponse{}
-//	err := clientKeyPair.DoAction(request, response)
-//	assert.Nil(t, err)
-//	assert.Equal(t, http.StatusOK, response.GetHttpStatus(), response.GetHttpContentString())
-//	assert.NotNil(t, response.GetHttpContentString())
-//
-//	var responseBean MockResponse
-//	json.Unmarshal([]byte(response.GetHttpContentString()), &responseBean)
-//
-//	assert.Equal(t, "QueryParamValue", responseBean.Params["QueryParam"])
-//}
+func TestRpcGetForKeyPair(t *testing.T) {
+	request := getFtTestRpcRequest()
+	request.Method = requests.GET
+
+	response := &responses.BaseResponse{}
+	err := clientKeyPair.DoAction(request, response)
+	assert.Nil(t, err)
+	assert.Equal(t, http.StatusOK, response.GetHttpStatus(), response.GetHttpContentString())
+	assert.NotNil(t, response.GetHttpContentString())
+
+	var responseBean MockResponse
+	json.Unmarshal([]byte(response.GetHttpContentString()), &responseBean)
+
+	assert.Equal(t, "QueryParamValue", responseBean.Params["QueryParam"])
+}
 
 /*func TestRpcGetForEcs(t *testing.T) {
 	//测试接口,想测试的时候,要替换掉singer_ecs_instance中对应的变量,并且还要提供一个mock服务
@@ -461,12 +487,38 @@ func TestRpcGetForLocationCache(t *testing.T) {
 	assert.Equal(t, "QueryParamValue", responseBean.Params["QueryParam"])
 }*/
 
-//func TestRpcGetForRoleArn(t *testing.T) {
+func TestRpcGetForRoleArn(t *testing.T) {
+	request := getFtTestRpcRequest()
+	request.Method = requests.GET
+
+	response := &responses.BaseResponse{}
+	err := clientRoleArn.DoAction(request, response)
+	assert.Nil(t, err)
+	assert.Equal(t, http.StatusOK, response.GetHttpStatus(), response.GetHttpContentString())
+	assert.NotNil(t, response.GetHttpContentString())
+
+	var responseBean MockResponse
+	json.Unmarshal([]byte(response.GetHttpContentString()), &responseBean)
+
+	assert.Equal(t, "QueryParamValue", responseBean.Params["QueryParam"])
+
+	err = clientRoleArn.DoAction(request, response)
+	assert.Nil(t, err)
+	assert.Equal(t, http.StatusOK, response.GetHttpStatus(), response.GetHttpContentString())
+	assert.NotNil(t, response.GetHttpContentString())
+
+	json.Unmarshal([]byte(response.GetHttpContentString()), &responseBean)
+
+	assert.Equal(t, "QueryParamValue", responseBean.Params["QueryParam"])
+}
+
+//测试Sts的时候要先获取一套stsToken和ak,由于有时效性,所以先把代码注释掉,测试的时候先获取stsToken完成后再调用
+//func TestRpcGetForSts(t *testing.T) {
 //	request := getFtTestRpcRequest()
 //	request.Method = requests.GET
 //
 //	response := &responses.BaseResponse{}
-//	err := clientRoleArn.DoAction(request, response)
+//	err := clientSts.DoAction(request, response)
 //	assert.Nil(t, err)
 //	assert.Equal(t, http.StatusOK, response.GetHttpStatus(), response.GetHttpContentString())
 //	assert.NotNil(t, response.GetHttpContentString())
@@ -475,15 +527,6 @@ func TestRpcGetForLocationCache(t *testing.T) {
 //	json.Unmarshal([]byte(response.GetHttpContentString()), &responseBean)
 //
 //	assert.Equal(t, "QueryParamValue", responseBean.Params["QueryParam"])
-//
-//	err = clientRoleArn.DoAction(request, response)
-//	assert.Nil(t, err)
-//	assert.Equal(t, http.StatusOK, response.GetHttpStatus(), response.GetHttpContentString())
-//	assert.NotNil(t, response.GetHttpContentString())
-//
-//	json.Unmarshal([]byte(response.GetHttpContentString()), &responseBean)
-//
-//	assert.Equal(t, "QueryParamValue", responseBean.Params["QueryParam"])
 //}
 
 func TestCommonRoaRequestForAcceptXML(t *testing.T) {

+ 1 - 1
sdk/config.go

@@ -25,7 +25,7 @@ type Config struct {
 	MaxRetryTime      int             `default:"3"`
 	UserAgent         string          `default:""`
 	Debug             bool            `default:"false"`
-	Timeout           time.Duration   `default:""`
+	Timeout           time.Duration   `default:"10000000000"`
 	HttpTransport     *http.Transport `default:""`
 	EnableAsync       bool            `default:"false"`
 	MaxTaskQueueSize  int             `default:"1000"`

+ 24 - 11
sdk/endpoints/location_resolver.go

@@ -16,6 +16,7 @@ package endpoints
 import (
 	"encoding/json"
 	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+	"sync"
 	"time"
 )
 
@@ -23,8 +24,15 @@ const (
 	EndpointCacheExpireTime = 3600 //Seconds
 )
 
-var lastClearTimePerProduct map[string]int64 = make(map[string]int64)
-var endpointCache map[string]string = make(map[string]string)
+var lastClearTimePerProduct = struct {
+	sync.RWMutex
+	cache map[string]int64
+}{cache: make(map[string]int64)}
+
+var endpointCache = struct {
+	sync.RWMutex
+	cache map[string]string
+}{cache: make(map[string]string)}
 
 type LocationResolver struct {
 }
@@ -37,8 +45,8 @@ func (resolver *LocationResolver) TryResolve(param *ResolveParam) (endpoint stri
 
 	//get from cache
 	cacheKey := param.Product + "#" + param.RegionId
-	if endpointCache != nil && len(endpointCache[cacheKey]) > 0 && !CheckCacheIsExpire(cacheKey) {
-		endpoint = endpointCache[cacheKey]
+	if endpointCache.cache != nil && len(endpointCache.cache[cacheKey]) > 0 && !CheckCacheIsExpire(cacheKey) {
+		endpoint = endpointCache.cache[cacheKey]
 		support = true
 		return
 	}
@@ -53,14 +61,13 @@ func (resolver *LocationResolver) TryResolve(param *ResolveParam) (endpoint stri
 
 	getEndpointRequest.QueryParams["Id"] = param.RegionId
 	getEndpointRequest.QueryParams["ServiceCode"] = param.LocationProduct
-	if len(param.LocationEndpoint) > 0 {
-		getEndpointRequest.QueryParams["Type"] = param.LocationEndpoint
+	if len(param.LocationEndpointType) > 0 {
+		getEndpointRequest.QueryParams["Type"] = param.LocationEndpointType
 	} else {
 		getEndpointRequest.QueryParams["Type"] = "openAPI"
 	}
 
 	response, err := param.CommonApi(getEndpointRequest)
-	//{"Endpoints":{"Endpoint":[{"Protocols":{"Protocols":["HTTP","HTTPS"]},"Type":"openAPI","Namespace":"26842","Id":"cn-hangzhou","SerivceCode":"apigateway","Endpoint":"apigateway.cn-hangzhou.aliyuncs.com"}]},"RequestId":"3287538B-19A0-4550-9995-143C5EDBD955","Success":true}
 	var getEndpointResponse GetEndpointResponse
 	if !response.IsSuccess() {
 		support = false
@@ -78,8 +85,12 @@ func (resolver *LocationResolver) TryResolve(param *ResolveParam) (endpoint stri
 	}
 	if len(getEndpointResponse.Endpoints.Endpoint[0].Endpoint) > 0 {
 		endpoint = getEndpointResponse.Endpoints.Endpoint[0].Endpoint
-		endpointCache[cacheKey] = endpoint
-		lastClearTimePerProduct[cacheKey] = time.Now().Unix()
+		endpointCache.Lock()
+		endpointCache.cache[cacheKey] = endpoint
+		endpointCache.Unlock()
+		lastClearTimePerProduct.Lock()
+		lastClearTimePerProduct.cache[cacheKey] = time.Now().Unix()
+		lastClearTimePerProduct.Unlock()
 		support = true
 		return
 	}
@@ -89,10 +100,12 @@ func (resolver *LocationResolver) TryResolve(param *ResolveParam) (endpoint stri
 }
 
 func CheckCacheIsExpire(cacheKey string) bool {
-	lastClearTime := lastClearTimePerProduct[cacheKey]
+	lastClearTime := lastClearTimePerProduct.cache[cacheKey]
 	if lastClearTime <= 0 {
 		lastClearTime = time.Now().Unix()
-		lastClearTimePerProduct[cacheKey] = lastClearTime
+		lastClearTimePerProduct.Lock()
+		lastClearTimePerProduct.cache[cacheKey] = lastClearTime
+		lastClearTimePerProduct.Unlock()
 	}
 
 	now := time.Now().Unix()

+ 8 - 8
sdk/endpoints/resolver.go

@@ -44,8 +44,8 @@ func Resolve(param *ResolveParam) (endpoint string, err error) {
 	}
 
 	// not support
-	errorMsg := fmt.Sprintf(errors.CanNotResolveEndpointMessage, param, ResolveEndpointUserGuideLink)
-	err = errors.NewClientError(errors.CanNotResolveEndpointCode, errorMsg, nil)
+	errorMsg := fmt.Sprintf(errors.CanNotResolveEndpointErrorMessage, param, ResolveEndpointUserGuideLink)
+	err = errors.NewClientError(errors.CanNotResolveEndpointErrorCode, errorMsg, nil)
 	return
 }
 
@@ -61,12 +61,12 @@ func getAllResolvers() []Resolver {
 }
 
 type ResolveParam struct {
-	Domain           string
-	Product          string
-	RegionId         string
-	LocationProduct  string
-	LocationEndpoint string
-	CommonApi        func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) `json:"-"`
+	Domain               string
+	Product              string
+	RegionId             string
+	LocationProduct      string
+	LocationEndpointType string
+	CommonApi            func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) `json:"-"`
 }
 
 func (param *ResolveParam) String() string {

+ 23 - 13
sdk/errors/client_error.go

@@ -20,23 +20,29 @@ const (
 	DefaultClientErrorStatus = 400
 	DefaultClientErrorCode   = "SDK.ClientError"
 
-	UnsupportedCredentialCode    = "SDK.UnsupportedCredential"
-	UnsupportedCredentialMessage = "Specified credential (type = %s) is not supported, please check"
+	UnsupportedCredentialErrorCode    = "SDK.UnsupportedCredential"
+	UnsupportedCredentialErrorMessage = "Specified credential (type = %s) is not supported, please check"
 
-	CanNotResolveEndpointCode    = "SDK.CanNotResolveEndpoint"
-	CanNotResolveEndpointMessage = "Can not resolve endpoint(param = %s), please check the user guide\n %s"
+	CanNotResolveEndpointErrorCode    = "SDK.CanNotResolveEndpoint"
+	CanNotResolveEndpointErrorMessage = "Can not resolve endpoint(param = %s), please check the user guide\n %s"
 
-	UnsupportedParamPositionCode    = "SDK.UnsupportedParamPosition"
-	UnsupportedParamPositionMessage = "Specified param position (%s) is not supported, please upgrade sdk and retry"
+	UnsupportedParamPositionErrorCode    = "SDK.UnsupportedParamPosition"
+	UnsupportedParamPositionErrorMessage = "Specified param position (%s) is not supported, please upgrade sdk and retry"
 
 	AsyncFunctionNotEnabledCode    = "SDK.AsyncFunctionNotEnabled"
 	AsyncFunctionNotEnabledMessage = "Async function is not enabled in client, please invoke 'client.EnableAsync' function"
 
-	UnknownRequestTypeCode    = "SDK.UnknownRequestType"
-	UnknownRequestTypeMessage = "Unknown Request Type: %s"
+	UnknownRequestTypeErrorCode    = "SDK.UnknownRequestType"
+	UnknownRequestTypeErrorMessage = "Unknown Request Type: %s"
 
-	MissingParamCode = "SDK.MissingParam"
-	InvalidParamCode = "SDK.InvalidParam"
+	MissingParamErrorCode = "SDK.MissingParam"
+	InvalidParamErrorCode = "SDK.InvalidParam"
+
+	JsonUnmarshalErrorCode    = "SDK.JsonUnmarshalError"
+	JsonUnmarshalErrorMessage = "Failed to unmarshal response, but you can get the data via response.GetHttpStatusCode() and response.GetHttpContentString()"
+
+	TimeoutErrorCode    = "SDK.TimeoutError"
+	TimeoutErrorMessage = "The request timed out %s times(%s for retry), perhaps we should have the threshold raised a little?"
 )
 
 type ClientError struct {
@@ -54,11 +60,11 @@ func NewClientError(errorCode, message string, originErr error) Error {
 }
 
 func (err *ClientError) Error() string {
+	clientErrMsg := fmt.Sprintf("[%s] %s", err.errorCode, err.message)
 	if err.originError != nil {
-		return err.originError.Error()
+		return clientErrMsg + "\ncaused by:\n" + err.originError.Error()
 	}
-
-	return fmt.Sprintf("[%s] %s", err.errorCode, err.message)
+	return clientErrMsg
 }
 
 func (err *ClientError) OriginError() error {
@@ -80,3 +86,7 @@ func (err *ClientError) ErrorCode() string {
 func (err *ClientError) Message() string {
 	return err.message
 }
+
+func (err *ClientError) String() string {
+	return err.Error()
+}

+ 2 - 2
sdk/requests/acs_reqeust.go

@@ -279,8 +279,8 @@ func addParam(request AcsRequest, position, name, value string) (err error) {
 		case Body:
 			request.addFormParam(name, value)
 		default:
-			errMsg := fmt.Sprintf(errors.UnsupportedParamPositionMessage, position)
-			err = errors.NewClientError(errors.UnsupportedParamPositionCode, errMsg, nil)
+			errMsg := fmt.Sprintf(errors.UnsupportedParamPositionErrorMessage, position)
+			err = errors.NewClientError(errors.UnsupportedParamPositionErrorCode, errMsg, nil)
 		}
 	}
 	return

+ 3 - 3
sdk/requests/common_request.go

@@ -31,13 +31,13 @@ func NewCommonRequest() (request *CommonRequest) {
 
 func (request *CommonRequest) TransToAcsRequest() {
 	if len(request.Version) == 0 {
-		errors.NewClientError(errors.MissingParamCode, "Common request [version] is required", nil)
+		errors.NewClientError(errors.MissingParamErrorCode, "Common request [version] is required", nil)
 	}
 	if len(request.ApiName) == 0 && len(request.PathPattern) == 0 {
-		errors.NewClientError(errors.MissingParamCode, "At least one of [ApiName] and [PathPattern] should has a value", nil)
+		errors.NewClientError(errors.MissingParamErrorCode, "At least one of [ApiName] and [PathPattern] should has a value", nil)
 	}
 	if len(request.Domain) == 0 && len(request.Product) == 0 {
-		errors.NewClientError(errors.MissingParamCode, "At least one of [Domain] and [Product] should has a value", nil)
+		errors.NewClientError(errors.MissingParamErrorCode, "At least one of [Domain] and [Product] should has a value", nil)
 	}
 
 	if len(request.PathPattern) > 0 {

+ 12 - 3
sdk/requests/types_test.go

@@ -10,7 +10,10 @@ func TestNewInteger(t *testing.T) {
 	assert.True(t, integer.hasValue())
 	value, err := integer.getValue()
 	assert.Nil(t, err)
-	assert.Equal(t, value, 123123)
+	assert.Equal(t, 123123, value)
+	var expected Integer
+	expected = "123123"
+	assert.Equal(t, expected, integer)
 }
 
 func TestNewBoolean(t *testing.T) {
@@ -18,7 +21,10 @@ func TestNewBoolean(t *testing.T) {
 	assert.True(t, boolean.hasValue())
 	value, err := boolean.getValue()
 	assert.Nil(t, err)
-	assert.Equal(t, value, false)
+	assert.Equal(t, false, value)
+	var expected Boolean
+	expected = "false"
+	assert.Equal(t, expected, boolean)
 }
 
 func TestNewFloat(t *testing.T) {
@@ -26,5 +32,8 @@ func TestNewFloat(t *testing.T) {
 	assert.True(t, float.hasValue())
 	value, err := float.getValue()
 	assert.Nil(t, err)
-	assert.Equal(t, value, 123123.123123)
+	assert.Equal(t, 123123.123123, value)
+	var expected Float
+	expected = "123123.123123"
+	assert.Equal(t, expected, float)
 }

+ 0 - 11
sdk/responses/json_parser_test.go

@@ -50,17 +50,6 @@ func TestFuzzyFieldUnmarshal(t *testing.T) {
 	assert.Equal(t, "", to.EmptyStrToStr)
 }
 
-//func TestFuzzyTypeUnmarshal(t *testing.T){
-//	arrayJson := "[{\"instance_type\":\"ecs.n4.large\",\"vpc_id\":\"\",\"vswitch_id\":\"\",\"vswitch_cidr\":\"\",\"image_id\":\"registry-internal.cn-beijing.aliyuncs.com/acs/agent\",\"data_disk_size\":0,\"data_disk_category\":\"cloud_ssd\",\"security_group_id\":\"sg-2ze57kc2cf36f9mrsrjx\",\"tags\":\"\",\"zone_id\":\"cn-beijing-a\",\"-\":\"PayByTraffic\",\"name\":\"Hello\",\"cluster_id\":\"ca737c2c04143464eaf439e245ceb1bf4\",\"size\":3,\"region_id\":\"cn-beijing\",\"network_mode\":\"classic\",\"subnet_cidr\":\"172.18.1.1/24\",\"state\":\"running\",\"master_url\":\"https://master4g7.cs-cn-beijing.aliyun.com:20019\",\"agent_version\":\"0.9-cdb96d4\",\"external_loadbalancer_id\":\"lb-2zegrgbsmjvxx1r1v26pn\",\"internal_master_url\":\"https://master4g7.cs-cn-beijing.aliyun-inc.com:20019\",\"port\":20019,\"node_status\":\"{\\\"health\\\":0,\\\"unhealth\\\":3}\",\"cluster_healthy\":\"unhealth\",\"docker_version\":\"17.06.1-ce\",\"cluster_type\":\"aliyun\",\"swarm_mode\":true,\"init_version\":\"\",\"current_version\":\"\",\"meta_data\":\"\",\"upgrade_components\":null,\"capabilities\":{\"acslogging\":true,\"acsrouting\":true,\"blue-green_confirm\":true,\"blue-green_deployment\":true,\"cluster_event\":true,\"compose_v2\":true,\"config_map\":true,\"cron\":true,\"default_update_method\":true,\"drain\":true,\"logging_sls\":true,\"monitoring\":true,\"node_scaling\":true,\"porject_event_deletion\":true,\"porject_trigger\":true,\"rebalance\":true,\"reset_node\":true,\"routing_custom_root_domain\":true,\"routing_slb\":true,\"scalingtrigger\":true,\"slb-blue-green_deployment\":true,\"update_force_reschedule\":true,\"volume_ossfs\":true,\"volume_yunpan\":true},\"need_update_agent\":false,\"created\":\"2017-09-12T07:26:58Z\",\"updated\":\"2017-12-26T11:36:41Z\",\"outputs\":null,\"parameters\":null}]"
-//	commonResponse := NewCommonResponse()
-//	// support auto json type trans
-//	initJsonParserOnce()
-//	err := jsonParser.Unmarshal([]byte(arrayJson), commonResponse)
-//	if err != nil {
-//		panic(err)
-//	}
-//}
-
 func getJsonBytes() ([]byte, error) {
 	from := &From{
 		StrToStr:            "demo string",

+ 7 - 0
sdk/responses/response.go

@@ -43,9 +43,16 @@ func Unmarshal(response AcsResponse, httpResponse *http.Response, format string)
 		err = errors.NewServerError(response.GetHttpStatus(), response.GetOriginHttpResponse().Status, response.GetHttpContentString())
 		return
 	}
+	if _, isCommonResponse := response.(CommonResponse); isCommonResponse {
+		// common response need not unmarshal
+		return
+	}
 	if strings.ToUpper(format) == "JSON" {
 		initJsonParserOnce()
 		err = jsonParser.Unmarshal(response.GetHttpContentBytes(), response)
+		if err != nil {
+			err = errors.NewClientError(errors.JsonUnmarshalErrorCode, errors.JsonUnmarshalErrorMessage, err)
+		}
 	} else if strings.ToUpper(format) == "XML" {
 		err = xml.Unmarshal(response.GetHttpContentBytes(), response)
 	}

+ 3 - 0
sdk/utils/utils.go

@@ -90,6 +90,9 @@ func InitStructWithDefaultTag(bean interface{}) {
 		case "int":
 			intValue, _ := strconv.ParseInt(defaultValue, 10, 64)
 			setter.SetInt(intValue)
+		case "time.Duration":
+			intValue, _ := strconv.ParseInt(defaultValue, 10, 64)
+			setter.SetInt(intValue)
 		case "string":
 			setter.SetString(defaultValue)
 		case "bool":

+ 60 - 60
vendor/github.com/jmespath/go-jmespath/functions.go

@@ -124,197 +124,197 @@ type functionCaller struct {
 func newFunctionCaller() *functionCaller {
 	caller := &functionCaller{}
 	caller.functionTable = map[string]functionEntry{
-		"length": functionEntry{
+		"length": {
 			name: "length",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpString, jpArray, jpObject}},
+				{types: []jpType{jpString, jpArray, jpObject}},
 			},
 			handler: jpfLength,
 		},
-		"starts_with": functionEntry{
+		"starts_with": {
 			name: "starts_with",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpString}},
-				argSpec{types: []jpType{jpString}},
+				{types: []jpType{jpString}},
+				{types: []jpType{jpString}},
 			},
 			handler: jpfStartsWith,
 		},
-		"abs": functionEntry{
+		"abs": {
 			name: "abs",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpNumber}},
+				{types: []jpType{jpNumber}},
 			},
 			handler: jpfAbs,
 		},
-		"avg": functionEntry{
+		"avg": {
 			name: "avg",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArrayNumber}},
+				{types: []jpType{jpArrayNumber}},
 			},
 			handler: jpfAvg,
 		},
-		"ceil": functionEntry{
+		"ceil": {
 			name: "ceil",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpNumber}},
+				{types: []jpType{jpNumber}},
 			},
 			handler: jpfCeil,
 		},
-		"contains": functionEntry{
+		"contains": {
 			name: "contains",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArray, jpString}},
-				argSpec{types: []jpType{jpAny}},
+				{types: []jpType{jpArray, jpString}},
+				{types: []jpType{jpAny}},
 			},
 			handler: jpfContains,
 		},
-		"ends_with": functionEntry{
+		"ends_with": {
 			name: "ends_with",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpString}},
-				argSpec{types: []jpType{jpString}},
+				{types: []jpType{jpString}},
+				{types: []jpType{jpString}},
 			},
 			handler: jpfEndsWith,
 		},
-		"floor": functionEntry{
+		"floor": {
 			name: "floor",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpNumber}},
+				{types: []jpType{jpNumber}},
 			},
 			handler: jpfFloor,
 		},
-		"map": functionEntry{
+		"map": {
 			name: "amp",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpExpref}},
-				argSpec{types: []jpType{jpArray}},
+				{types: []jpType{jpExpref}},
+				{types: []jpType{jpArray}},
 			},
 			handler:   jpfMap,
 			hasExpRef: true,
 		},
-		"max": functionEntry{
+		"max": {
 			name: "max",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArrayNumber, jpArrayString}},
+				{types: []jpType{jpArrayNumber, jpArrayString}},
 			},
 			handler: jpfMax,
 		},
-		"merge": functionEntry{
+		"merge": {
 			name: "merge",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpObject}, variadic: true},
+				{types: []jpType{jpObject}, variadic: true},
 			},
 			handler: jpfMerge,
 		},
-		"max_by": functionEntry{
+		"max_by": {
 			name: "max_by",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArray}},
-				argSpec{types: []jpType{jpExpref}},
+				{types: []jpType{jpArray}},
+				{types: []jpType{jpExpref}},
 			},
 			handler:   jpfMaxBy,
 			hasExpRef: true,
 		},
-		"sum": functionEntry{
+		"sum": {
 			name: "sum",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArrayNumber}},
+				{types: []jpType{jpArrayNumber}},
 			},
 			handler: jpfSum,
 		},
-		"min": functionEntry{
+		"min": {
 			name: "min",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArrayNumber, jpArrayString}},
+				{types: []jpType{jpArrayNumber, jpArrayString}},
 			},
 			handler: jpfMin,
 		},
-		"min_by": functionEntry{
+		"min_by": {
 			name: "min_by",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArray}},
-				argSpec{types: []jpType{jpExpref}},
+				{types: []jpType{jpArray}},
+				{types: []jpType{jpExpref}},
 			},
 			handler:   jpfMinBy,
 			hasExpRef: true,
 		},
-		"type": functionEntry{
+		"type": {
 			name: "type",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpAny}},
+				{types: []jpType{jpAny}},
 			},
 			handler: jpfType,
 		},
-		"keys": functionEntry{
+		"keys": {
 			name: "keys",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpObject}},
+				{types: []jpType{jpObject}},
 			},
 			handler: jpfKeys,
 		},
-		"values": functionEntry{
+		"values": {
 			name: "values",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpObject}},
+				{types: []jpType{jpObject}},
 			},
 			handler: jpfValues,
 		},
-		"sort": functionEntry{
+		"sort": {
 			name: "sort",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArrayString, jpArrayNumber}},
+				{types: []jpType{jpArrayString, jpArrayNumber}},
 			},
 			handler: jpfSort,
 		},
-		"sort_by": functionEntry{
+		"sort_by": {
 			name: "sort_by",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArray}},
-				argSpec{types: []jpType{jpExpref}},
+				{types: []jpType{jpArray}},
+				{types: []jpType{jpExpref}},
 			},
 			handler:   jpfSortBy,
 			hasExpRef: true,
 		},
-		"join": functionEntry{
+		"join": {
 			name: "join",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpString}},
-				argSpec{types: []jpType{jpArrayString}},
+				{types: []jpType{jpString}},
+				{types: []jpType{jpArrayString}},
 			},
 			handler: jpfJoin,
 		},
-		"reverse": functionEntry{
+		"reverse": {
 			name: "reverse",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArray, jpString}},
+				{types: []jpType{jpArray, jpString}},
 			},
 			handler: jpfReverse,
 		},
-		"to_array": functionEntry{
+		"to_array": {
 			name: "to_array",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpAny}},
+				{types: []jpType{jpAny}},
 			},
 			handler: jpfToArray,
 		},
-		"to_string": functionEntry{
+		"to_string": {
 			name: "to_string",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpAny}},
+				{types: []jpType{jpAny}},
 			},
 			handler: jpfToString,
 		},
-		"to_number": functionEntry{
+		"to_number": {
 			name: "to_number",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpAny}},
+				{types: []jpType{jpAny}},
 			},
 			handler: jpfToNumber,
 		},
-		"not_null": functionEntry{
+		"not_null": {
 			name: "not_null",
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpAny}, variadic: true},
+				{types: []jpType{jpAny}, variadic: true},
 			},
 			handler: jpfNotNull,
 		},

+ 6 - 6
vendor/github.com/jmespath/go-jmespath/interpreter_test.go

@@ -69,7 +69,7 @@ func TestCanSupportUserDefinedStructsRef(t *testing.T) {
 
 func TestCanSupportStructWithSliceAll(t *testing.T) {
 	assert := assert.New(t)
-	data := sliceType{A: "foo", B: []scalars{scalars{"f1", "b1"}, scalars{"correct", "b2"}}}
+	data := sliceType{A: "foo", B: []scalars{{"f1", "b1"}, {"correct", "b2"}}}
 	result, err := Search("B[].Foo", data)
 	assert.Nil(err)
 	assert.Equal([]interface{}{"f1", "correct"}, result)
@@ -77,7 +77,7 @@ func TestCanSupportStructWithSliceAll(t *testing.T) {
 
 func TestCanSupportStructWithSlicingExpression(t *testing.T) {
 	assert := assert.New(t)
-	data := sliceType{A: "foo", B: []scalars{scalars{"f1", "b1"}, scalars{"correct", "b2"}}}
+	data := sliceType{A: "foo", B: []scalars{{"f1", "b1"}, {"correct", "b2"}}}
 	result, err := Search("B[:].Foo", data)
 	assert.Nil(err)
 	assert.Equal([]interface{}{"f1", "correct"}, result)
@@ -85,7 +85,7 @@ func TestCanSupportStructWithSlicingExpression(t *testing.T) {
 
 func TestCanSupportStructWithFilterProjection(t *testing.T) {
 	assert := assert.New(t)
-	data := sliceType{A: "foo", B: []scalars{scalars{"f1", "b1"}, scalars{"correct", "b2"}}}
+	data := sliceType{A: "foo", B: []scalars{{"f1", "b1"}, {"correct", "b2"}}}
 	result, err := Search("B[? `true` ].Foo", data)
 	assert.Nil(err)
 	assert.Equal([]interface{}{"f1", "correct"}, result)
@@ -93,7 +93,7 @@ func TestCanSupportStructWithFilterProjection(t *testing.T) {
 
 func TestCanSupportStructWithSlice(t *testing.T) {
 	assert := assert.New(t)
-	data := sliceType{A: "foo", B: []scalars{scalars{"f1", "b1"}, scalars{"correct", "b2"}}}
+	data := sliceType{A: "foo", B: []scalars{{"f1", "b1"}, {"correct", "b2"}}}
 	result, err := Search("B[-1].Foo", data)
 	assert.Nil(err)
 	assert.Equal("correct", result)
@@ -109,7 +109,7 @@ func TestCanSupportStructWithOrExpressions(t *testing.T) {
 
 func TestCanSupportStructWithSlicePointer(t *testing.T) {
 	assert := assert.New(t)
-	data := sliceType{A: "foo", C: []*scalars{&scalars{"f1", "b1"}, &scalars{"correct", "b2"}}}
+	data := sliceType{A: "foo", C: []*scalars{{"f1", "b1"}, {"correct", "b2"}}}
 	result, err := Search("C[-1].Foo", data)
 	assert.Nil(err)
 	assert.Equal("correct", result)
@@ -128,7 +128,7 @@ func TestWillAutomaticallyCapitalizeFieldNames(t *testing.T) {
 
 func TestCanSupportStructWithSliceLowerCased(t *testing.T) {
 	assert := assert.New(t)
-	data := sliceType{A: "foo", B: []scalars{scalars{"f1", "b1"}, scalars{"correct", "b2"}}}
+	data := sliceType{A: "foo", B: []scalars{{"f1", "b1"}, {"correct", "b2"}}}
 	result, err := Search("b[-1].foo", data)
 	assert.Nil(err)
 	assert.Equal("correct", result)

+ 49 - 49
vendor/github.com/jmespath/go-jmespath/lexer_test.go

@@ -11,63 +11,63 @@ var lexingTests = []struct {
 	expression string
 	expected   []token
 }{
-	{"*", []token{token{tStar, "*", 0, 1}}},
-	{".", []token{token{tDot, ".", 0, 1}}},
-	{"[?", []token{token{tFilter, "[?", 0, 2}}},
-	{"[]", []token{token{tFlatten, "[]", 0, 2}}},
-	{"(", []token{token{tLparen, "(", 0, 1}}},
-	{")", []token{token{tRparen, ")", 0, 1}}},
-	{"[", []token{token{tLbracket, "[", 0, 1}}},
-	{"]", []token{token{tRbracket, "]", 0, 1}}},
-	{"{", []token{token{tLbrace, "{", 0, 1}}},
-	{"}", []token{token{tRbrace, "}", 0, 1}}},
-	{"||", []token{token{tOr, "||", 0, 2}}},
-	{"|", []token{token{tPipe, "|", 0, 1}}},
-	{"29", []token{token{tNumber, "29", 0, 2}}},
-	{"2", []token{token{tNumber, "2", 0, 1}}},
-	{"0", []token{token{tNumber, "0", 0, 1}}},
-	{"-20", []token{token{tNumber, "-20", 0, 3}}},
-	{"foo", []token{token{tUnquotedIdentifier, "foo", 0, 3}}},
-	{`"bar"`, []token{token{tQuotedIdentifier, "bar", 0, 3}}},
+	{"*", []token{{tStar, "*", 0, 1}}},
+	{".", []token{{tDot, ".", 0, 1}}},
+	{"[?", []token{{tFilter, "[?", 0, 2}}},
+	{"[]", []token{{tFlatten, "[]", 0, 2}}},
+	{"(", []token{{tLparen, "(", 0, 1}}},
+	{")", []token{{tRparen, ")", 0, 1}}},
+	{"[", []token{{tLbracket, "[", 0, 1}}},
+	{"]", []token{{tRbracket, "]", 0, 1}}},
+	{"{", []token{{tLbrace, "{", 0, 1}}},
+	{"}", []token{{tRbrace, "}", 0, 1}}},
+	{"||", []token{{tOr, "||", 0, 2}}},
+	{"|", []token{{tPipe, "|", 0, 1}}},
+	{"29", []token{{tNumber, "29", 0, 2}}},
+	{"2", []token{{tNumber, "2", 0, 1}}},
+	{"0", []token{{tNumber, "0", 0, 1}}},
+	{"-20", []token{{tNumber, "-20", 0, 3}}},
+	{"foo", []token{{tUnquotedIdentifier, "foo", 0, 3}}},
+	{`"bar"`, []token{{tQuotedIdentifier, "bar", 0, 3}}},
 	// Escaping the delimiter
-	{`"bar\"baz"`, []token{token{tQuotedIdentifier, `bar"baz`, 0, 7}}},
-	{",", []token{token{tComma, ",", 0, 1}}},
-	{":", []token{token{tColon, ":", 0, 1}}},
-	{"<", []token{token{tLT, "<", 0, 1}}},
-	{"<=", []token{token{tLTE, "<=", 0, 2}}},
-	{">", []token{token{tGT, ">", 0, 1}}},
-	{">=", []token{token{tGTE, ">=", 0, 2}}},
-	{"==", []token{token{tEQ, "==", 0, 2}}},
-	{"!=", []token{token{tNE, "!=", 0, 2}}},
-	{"`[0, 1, 2]`", []token{token{tJSONLiteral, "[0, 1, 2]", 1, 9}}},
-	{"'foo'", []token{token{tStringLiteral, "foo", 1, 3}}},
-	{"'a'", []token{token{tStringLiteral, "a", 1, 1}}},
-	{`'foo\'bar'`, []token{token{tStringLiteral, "foo'bar", 1, 7}}},
-	{"@", []token{token{tCurrent, "@", 0, 1}}},
-	{"&", []token{token{tExpref, "&", 0, 1}}},
+	{`"bar\"baz"`, []token{{tQuotedIdentifier, `bar"baz`, 0, 7}}},
+	{",", []token{{tComma, ",", 0, 1}}},
+	{":", []token{{tColon, ":", 0, 1}}},
+	{"<", []token{{tLT, "<", 0, 1}}},
+	{"<=", []token{{tLTE, "<=", 0, 2}}},
+	{">", []token{{tGT, ">", 0, 1}}},
+	{">=", []token{{tGTE, ">=", 0, 2}}},
+	{"==", []token{{tEQ, "==", 0, 2}}},
+	{"!=", []token{{tNE, "!=", 0, 2}}},
+	{"`[0, 1, 2]`", []token{{tJSONLiteral, "[0, 1, 2]", 1, 9}}},
+	{"'foo'", []token{{tStringLiteral, "foo", 1, 3}}},
+	{"'a'", []token{{tStringLiteral, "a", 1, 1}}},
+	{`'foo\'bar'`, []token{{tStringLiteral, "foo'bar", 1, 7}}},
+	{"@", []token{{tCurrent, "@", 0, 1}}},
+	{"&", []token{{tExpref, "&", 0, 1}}},
 	// Quoted identifier unicode escape sequences
-	{`"\u2713"`, []token{token{tQuotedIdentifier, "✓", 0, 3}}},
-	{`"\\"`, []token{token{tQuotedIdentifier, `\`, 0, 1}}},
-	{"`\"foo\"`", []token{token{tJSONLiteral, "\"foo\"", 1, 5}}},
+	{`"\u2713"`, []token{{tQuotedIdentifier, "✓", 0, 3}}},
+	{`"\\"`, []token{{tQuotedIdentifier, `\`, 0, 1}}},
+	{"`\"foo\"`", []token{{tJSONLiteral, "\"foo\"", 1, 5}}},
 	// Combinations of tokens.
 	{"foo.bar", []token{
-		token{tUnquotedIdentifier, "foo", 0, 3},
-		token{tDot, ".", 3, 1},
-		token{tUnquotedIdentifier, "bar", 4, 3},
+		{tUnquotedIdentifier, "foo", 0, 3},
+		{tDot, ".", 3, 1},
+		{tUnquotedIdentifier, "bar", 4, 3},
 	}},
 	{"foo[0]", []token{
-		token{tUnquotedIdentifier, "foo", 0, 3},
-		token{tLbracket, "[", 3, 1},
-		token{tNumber, "0", 4, 1},
-		token{tRbracket, "]", 5, 1},
+		{tUnquotedIdentifier, "foo", 0, 3},
+		{tLbracket, "[", 3, 1},
+		{tNumber, "0", 4, 1},
+		{tRbracket, "]", 5, 1},
 	}},
 	{"foo[?a<b]", []token{
-		token{tUnquotedIdentifier, "foo", 0, 3},
-		token{tFilter, "[?", 3, 2},
-		token{tUnquotedIdentifier, "a", 5, 1},
-		token{tLT, "<", 6, 1},
-		token{tUnquotedIdentifier, "b", 7, 1},
-		token{tRbracket, "]", 8, 1},
+		{tUnquotedIdentifier, "foo", 0, 3},
+		{tFilter, "[?", 3, 2},
+		{tUnquotedIdentifier, "a", 5, 1},
+		{tLT, "<", 6, 1},
+		{tUnquotedIdentifier, "b", 7, 1},
+		{tRbracket, "]", 8, 1},
 	}},
 }
 

+ 2 - 2
vendor/github.com/jmespath/go-jmespath/parser.go

@@ -353,7 +353,7 @@ func (p *Parser) nud(token token) (ASTNode, error) {
 	case tFlatten:
 		left := ASTNode{
 			nodeType: ASTFlatten,
-			children: []ASTNode{ASTNode{nodeType: ASTIdentity}},
+			children: []ASTNode{{nodeType: ASTIdentity}},
 		}
 		right, err := p.parseProjectionRHS(bindingPowers[tFlatten])
 		if err != nil {
@@ -378,7 +378,7 @@ func (p *Parser) nud(token token) (ASTNode, error) {
 			}
 			return ASTNode{
 				nodeType: ASTProjection,
-				children: []ASTNode{ASTNode{nodeType: ASTIdentity}, right},
+				children: []ASTNode{{nodeType: ASTIdentity}, right},
 			}, nil
 		} else {
 			return p.parseMultiSelectList()

+ 1 - 1
vendor/github.com/jmespath/go-jmespath/util_test.go

@@ -13,7 +13,7 @@ func TestSlicePositiveStep(t *testing.T) {
 	input[2] = 2
 	input[3] = 3
 	input[4] = 4
-	result, err := slice(input, []sliceParam{sliceParam{0, true}, sliceParam{3, true}, sliceParam{1, true}})
+	result, err := slice(input, []sliceParam{{0, true}, {3, true}, {1, true}})
 	assert.Nil(err)
 	assert.Equal(input[:3], result)
 }

+ 3 - 3
vendor/github.com/stretchr/testify/mock/mock_test.go

@@ -126,13 +126,13 @@ func Test_Mock_Chained_On(t *testing.T) {
 		Return(nil)
 
 	expectedCalls := []*Call{
-		&Call{
+		{
 			Parent:          &mockedService.Mock,
 			Method:          "TheExampleMethod",
 			Arguments:       []interface{}{1, 2, 3},
 			ReturnArguments: []interface{}{0},
 		},
-		&Call{
+		{
 			Parent:          &mockedService.Mock,
 			Method:          "TheExampleMethod3",
 			Arguments:       []interface{}{AnythingOfType("*mock.ExampleType")},
@@ -1342,7 +1342,7 @@ func TestAfterTotalWaitTimeWhileExecution(t *testing.T) {
 	elapsedTime := end.Sub(start)
 	assert.True(t, elapsedTime > waitMs, fmt.Sprintf("Total elapsed time:%v should be atleast greater than %v", elapsedTime, waitMs))
 	assert.Equal(t, total, len(results))
-	for i, _ := range results {
+	for i := range results {
 		assert.Equal(t, fmt.Sprintf("Time%d", i), results[i], "Return value of method should be same")
 	}
 }

+ 2 - 2
vendor/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/format_test.go

@@ -1536,14 +1536,14 @@ func TestPrintSortedKeys(t *testing.T) {
 		t.Errorf("Sorted keys mismatch 3:\n  %v %v", s, expected)
 	}
 
-	s = cfg.Sprint(map[testStruct]int{testStruct{1}: 1, testStruct{3}: 3, testStruct{2}: 2})
+	s = cfg.Sprint(map[testStruct]int{{1}: 1, {3}: 3, {2}: 2})
 	expected = "map[ts.1:1 ts.2:2 ts.3:3]"
 	if s != expected {
 		t.Errorf("Sorted keys mismatch 4:\n  %v %v", s, expected)
 	}
 
 	if !spew.UnsafeDisabled {
-		s = cfg.Sprint(map[testStructP]int{testStructP{1}: 1, testStructP{3}: 3, testStructP{2}: 2})
+		s = cfg.Sprint(map[testStructP]int{{1}: 1, {3}: 3, {2}: 2})
 		expected = "map[ts.1:1 ts.2:2 ts.3:3]"
 		if s != expected {
 			t.Errorf("Sorted keys mismatch 5:\n  %v %v", s, expected)

+ 4 - 4
vendor/github.com/stretchr/testify/vendor/github.com/pmezard/go-difflib/difflib/difflib.go

@@ -161,12 +161,12 @@ func (m *SequenceMatcher) chainB() {
 	m.bJunk = map[string]struct{}{}
 	if m.IsJunk != nil {
 		junk := m.bJunk
-		for s, _ := range b2j {
+		for s := range b2j {
 			if m.IsJunk(s) {
 				junk[s] = struct{}{}
 			}
 		}
-		for s, _ := range junk {
+		for s := range junk {
 			delete(b2j, s)
 		}
 	}
@@ -181,7 +181,7 @@ func (m *SequenceMatcher) chainB() {
 				popular[s] = struct{}{}
 			}
 		}
-		for s, _ := range popular {
+		for s := range popular {
 			delete(b2j, s)
 		}
 	}
@@ -416,7 +416,7 @@ func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode {
 	}
 	codes := m.GetOpCodes()
 	if len(codes) == 0 {
-		codes = []OpCode{OpCode{'e', 0, 1, 0, 1}}
+		codes = []OpCode{{'e', 0, 1, 0, 1}}
 	}
 	// Fixup leading and trailing groups if they show no changes.
 	if codes[0].Tag == 'e' {

+ 2 - 2
vendor/github.com/stretchr/testify/vendor/github.com/pmezard/go-difflib/difflib/difflib_test.go

@@ -206,14 +206,14 @@ func TestWithAsciiBJunk(t *testing.T) {
 
 	sm = NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)),
 		splitChars(rep("a", 44)+rep("b", 40)+rep(" ", 20)), false, isJunk)
-	assertEqual(t, sm.bJunk, map[string]struct{}{" ": struct{}{}})
+	assertEqual(t, sm.bJunk, map[string]struct{}{" ": {}})
 
 	isJunk = func(s string) bool {
 		return s == " " || s == "b"
 	}
 	sm = NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)),
 		splitChars(rep("a", 44)+rep("b", 40)+rep(" ", 20)), false, isJunk)
-	assertEqual(t, sm.bJunk, map[string]struct{}{" ": struct{}{}, "b": struct{}{}})
+	assertEqual(t, sm.bJunk, map[string]struct{}{" ": {}, "b": {}})
 }
 
 func TestSFBugsRatioForNullSeqn(t *testing.T) {