Jelajahi Sumber

Merge pull request #29 from aliyun/test

publish 0.8.1
gaort 8 tahun lalu
induk
melakukan
dc8dcaff2a
44 mengubah file dengan 824 tambahan dan 341 penghapusan
  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
 2018-01-18 Version: 0.8.1
 1, Update ECS go SDK to catch up with other langs.
 1, Update ECS go SDK to catch up with other langs.
 2, DescribeImageSupportInstanceTypes add new param Filter and ActionType
 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 (
 import (
 	"fmt"
 	"fmt"
+	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
 	"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
 	"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/assert"
+	"strconv"
+	"strings"
 	"testing"
 	"testing"
 	"time"
 	"time"
-	"strings"
-	"strconv"
 )
 )
 
 
 const (
 const (
 	EcsInstanceDefaultTimeout = 120
 	EcsInstanceDefaultTimeout = 120
 	EcsDefaultWaitForInterval = 20
 	EcsDefaultWaitForInterval = 20
 
 
-	EcsInstanceStatusRunning  = "Running"
-	EcsInstanceStatusStopped  = "Stopped"
-	EcsInstanceStatusDeleted  = "Deleted"
+	EcsInstanceStatusRunning = "Running"
+	EcsInstanceStatusStopped = "Stopped"
+	EcsInstanceStatusDeleted = "Deleted"
 )
 )
 
 
 // create -> start -> stop -> delete
 // create -> start -> stop -> delete
@@ -55,7 +56,7 @@ func TestEcsInstance(t *testing.T) {
 	// wait
 	// wait
 	waitForEcsInstance(t, ecsClient, instanceId, EcsInstanceStatusStopped, 600)
 	waitForEcsInstance(t, ecsClient, instanceId, EcsInstanceStatusStopped, 600)
 
 
-	// delete all test instance
+	//delete all test instance
 	deleteAllTestEcsInstance(t, ecsClient)
 	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) {
 func deleteAllTestEcsInstance(t *testing.T, client *ecs.Client) {
 	fmt.Print("list all ecs instances...")
 	fmt.Print("list all ecs instances...")
 	request := ecs.CreateDescribeInstancesRequest()
 	request := ecs.CreateDescribeInstancesRequest()
-	request.PageSize = "10"
-	request.PageNumber = "1"
+	request.PageSize = requests.NewInteger(10)
+	request.PageNumber = requests.NewInteger(1)
 	response, err := client.DescribeInstances(request)
 	response, err := client.DescribeInstances(request)
 	assertErrorNil(t, err, "Failed to list all ecs instances ")
 	assertErrorNil(t, err, "Failed to list all ecs instances ")
 	assert.Equal(t, 200, response.GetHttpStatus(), response.GetHttpContentString())
 	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 {
 	for _, instanceInfo := range response.Instances.Instance {
 		if strings.HasPrefix(instanceInfo.InstanceName, InstanceNamePrefix) {
 		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) {
 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 (
 import (
 	"fmt"
 	"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/sdk/utils"
+	"github.com/aliyun/alibaba-cloud-sdk-go/services/slb"
+	"github.com/stretchr/testify/assert"
 	"net/http"
 	"net/http"
+	"strconv"
 	"strings"
 	"strings"
+	"testing"
+	"time"
 )
 )
 
 
 const (
 const (
@@ -128,18 +128,25 @@ func deleteAllTestSlbInstance(t *testing.T, client *slb.Client) {
 	response, err := client.DescribeLoadBalancers(request)
 	response, err := client.DescribeLoadBalancers(request)
 	assertErrorNil(t, err, "Failed to list all slb instances")
 	assertErrorNil(t, err, "Failed to list all slb instances")
 	assert.Equal(t, 200, response.GetHttpStatus(), response.GetHttpContentString())
 	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 {
 	for _, slbInstanceInfo := range response.LoadBalancers.LoadBalancer {
 		if strings.HasPrefix(slbInstanceInfo.LoadBalancerName, InstanceNamePrefix) {
 		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
 package integration
 
 
 import (
 import (
+	"fmt"
 	"os"
 	"os"
 	"testing"
 	"testing"
-	"fmt"
 )
 )
 
 
-const InstanceNamePrefix  = "SdkIntegrationTestInstance"
+const InstanceNamePrefix = "SdkIntegrationTestInstance"
 
 
 type Config struct {
 type Config struct {
 	AccessKeyId     string
 	AccessKeyId     string
@@ -29,13 +29,12 @@ func getConfigFromEnv() *Config {
 		ChildSecret:     os.Getenv("CHILD_SECRET"),
 		ChildSecret:     os.Getenv("CHILD_SECRET"),
 	}
 	}
 	if config.AccessKeyId == "" {
 	if config.AccessKeyId == "" {
-		return nil
+		panic("Get ACCESS_KEY_ID from environment variables failed")
 	} else {
 	} else {
 		return config
 		return config
 	}
 	}
 }
 }
 
 
-
 func getEcsDemoInstanceId() string {
 func getEcsDemoInstanceId() string {
 	return os.Getenv("DEMO_ECS_INSTANCE_ID")
 	return os.Getenv("DEMO_ECS_INSTANCE_ID")
 }
 }
@@ -44,4 +43,4 @@ func assertErrorNil(t *testing.T, err error, message string) {
 	if err != nil {
 	if err != nil {
 		fmt.Fprintf(os.Stderr, message+": %v\n", err)
 		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)
 			signer, err = signers.NewSignerV1(instance)
 		}
 		}
-	case *credentials.StsCredential:
+	case *credentials.StsTokenCredential:
 		{
 		{
 			signer, err = signers.NewSignerSts(instance)
 			signer, err = signers.NewSignerSts(instance)
 		}
 		}
-	case *credentials.StsAssumeRoleCredential:
+	case *credentials.StsRoleArnCredential:
 		{
 		{
 			signer, err = signers.NewSignerStsAssumeRole(instance, commonApi)
 			signer, err = signers.NewSignerStsAssumeRole(instance, commonApi)
 		}
 		}
-	case *credentials.KeyPairCredential:
+	case *credentials.RsaKeyPairCredential:
 		{
 		{
 			signer, err = signers.NewSignerKeyPair(instance, commonApi)
 			signer, err = signers.NewSignerKeyPair(instance, commonApi)
 		}
 		}
-	case *credentials.EcsInstanceCredential:
+	case *credentials.StsRoleNameOnEcsCredential:
 		{
 		{
 			signer, err = signers.NewSignereEcsInstance(instance, commonApi)
 			signer, err = signers.NewSignereEcsInstance(instance, commonApi)
 		}
 		}
 	default:
 	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
 	return
 }
 }
@@ -74,8 +74,8 @@ func Sign(request requests.AcsRequest, signer Signer, regionId string) (err erro
 			signRpcRequest(request, signer, regionId)
 			signRpcRequest(request, signer, regionId)
 		}
 		}
 	default:
 	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
 	return

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

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

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

@@ -29,7 +29,7 @@ import (
 type SignerKeyPair struct {
 type SignerKeyPair struct {
 	*credentialUpdater
 	*credentialUpdater
 	sessionCredential *SessionAkCredential
 	sessionCredential *SessionAkCredential
-	credential        *credentials.KeyPairCredential
+	credential        *credentials.RsaKeyPairCredential
 	commonApi         func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)
 	commonApi         func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)
 }
 }
 
 
@@ -38,7 +38,7 @@ type SessionAkCredential struct {
 	accessKeySecret string
 	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{
 	signer = &SignerKeyPair{
 		credential: credential,
 		credential: credential,
 		commonApi:  commonApi,
 		commonApi:  commonApi,
@@ -55,7 +55,7 @@ func NewSignerKeyPair(credential *credentials.KeyPairCredential, commonApi func(
 		if credential.SessionExpiration >= 900 && credential.SessionExpiration <= 3600 {
 		if credential.SessionExpiration >= 900 && credential.SessionExpiration <= 3600 {
 			signer.credentialExpiration = credential.SessionExpiration
 			signer.credentialExpiration = credential.SessionExpiration
 		} else {
 		} 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 {
 	} else {
 		signer.credentialExpiration = defaultDurationSeconds
 		signer.credentialExpiration = defaultDurationSeconds

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

@@ -19,10 +19,10 @@ import (
 )
 )
 
 
 type SignerSts struct {
 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{
 	return &SignerSts{
 		credential: credential,
 		credential: credential,
 	}, nil
 	}, nil

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

@@ -35,7 +35,7 @@ type SignerStsAssumeRole struct {
 	*credentialUpdater
 	*credentialUpdater
 	roleSessionName   string
 	roleSessionName   string
 	sessionCredential *sessionCredential
 	sessionCredential *sessionCredential
-	credential        *credentials.StsAssumeRoleCredential
+	credential        *credentials.StsRoleArnCredential
 	commonApi         func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)
 	commonApi         func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)
 }
 }
 
 
@@ -45,7 +45,7 @@ type sessionCredential struct {
 	securityToken   string
 	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{
 	signer = &SignerStsAssumeRole{
 		credential: credential,
 		credential: credential,
 		commonApi:  commonApi,
 		commonApi:  commonApi,
@@ -64,10 +64,10 @@ func NewSignerStsAssumeRole(credential *credentials.StsAssumeRoleCredential, com
 		signer.roleSessionName = "aliyun-go-sdk-" + strconv.FormatInt(time.Now().UnixNano()/1000, 10)
 		signer.roleSessionName = "aliyun-go-sdk-" + strconv.FormatInt(time.Now().UnixNano()/1000, 10)
 	}
 	}
 	if credential.RoleSessionExpiration > 0 {
 	if credential.RoleSessionExpiration > 0 {
-		if credential.RoleSessionExpiration > 900 && credential.RoleSessionExpiration < 3600 {
+		if credential.RoleSessionExpiration >= 900 && credential.RoleSessionExpiration <= 3600 {
 			signer.credentialExpiration = credential.RoleSessionExpiration
 			signer.credentialExpiration = credential.RoleSessionExpiration
 		} else {
 		} 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 {
 	} else {
 		signer.credentialExpiration = defaultDurationSeconds
 		signer.credentialExpiration = defaultDurationSeconds

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

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

+ 58 - 22
sdk/client.go

@@ -23,6 +23,8 @@ import (
 	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
 	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
 	"net"
 	"net"
 	"net/http"
 	"net/http"
+	"fmt"
+	"strconv"
 )
 )
 
 
 // this value will be replaced while build: -ldflags="-X sdk.version=x.x.x"
 // 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)
 	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()
 	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,
 		AccessKeyId:     accessKeyId,
 		AccessKeySecret: accessKeySecret,
 		AccessKeySecret: accessKeySecret,
 		RoleArn:         roleArn,
 		RoleArn:         roleArn,
@@ -103,9 +115,9 @@ func (client *Client) InitWithRoleArn(regionId, accessKeyId, accessKeySecret, ro
 	return client.InitWithOptions(regionId, config, credential)
 	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()
 	config := client.InitClientConfig()
-	credential := &credentials.KeyPairCredential{
+	credential := &credentials.RsaKeyPairCredential{
 		PrivateKey:        privateKey,
 		PrivateKey:        privateKey,
 		PublicKeyId:       publicKeyId,
 		PublicKeyId:       publicKeyId,
 		SessionExpiration: sessionExpiration,
 		SessionExpiration: sessionExpiration,
@@ -113,21 +125,20 @@ func (client *Client) InitWithKeyPair(regionId, publicKeyId, privateKey string,
 	return client.InitWithOptions(regionId, config, credential)
 	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()
 	config := client.InitClientConfig()
-	credential := &credentials.EcsInstanceCredential{
+	credential := &credentials.StsRoleNameOnEcsCredential{
 		RoleName: roleName,
 		RoleName: roleName,
 	}
 	}
 	return client.InitWithOptions(regionId, config, credential)
 	return client.InitWithOptions(regionId, config, credential)
 }
 }
 
 
 func (client *Client) InitClientConfig() (config *Config) {
 func (client *Client) InitClientConfig() (config *Config) {
-	config = NewConfig()
 	if client.config != nil {
 	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) {
 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
 	// resolve endpoint
 	resolveParam := &endpoints.ResolveParam{
 	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)
 	endpoint, err := endpoints.Resolve(resolveParam)
 	if err != nil {
 	if err != nil {
@@ -190,20 +201,21 @@ func (client *Client) DoActionWithSigner(request requests.AcsRequest, response r
 	for retryTimes := 0; retryTimes <= client.config.MaxRetryTime; retryTimes++ {
 	for retryTimes := 0; retryTimes <= client.config.MaxRetryTime; retryTimes++ {
 		httpResponse, err = client.httpClient.Do(httpRequest)
 		httpResponse, err = client.httpClient.Do(httpRequest)
 
 
-		// retry params
 		var timeout bool
 		var timeout bool
-		var serverError bool
-
 		// receive error
 		// receive error
 		if err != nil {
 		if err != nil {
-			// if not timeout error, return
 			if timeout = isTimeout(err); !timeout {
 			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
 				return
 			}
 			}
 		}
 		}
-		serverError = isServerError(httpResponse)
 		//  if status code >= 500 or timeout, will trigger retry
 		//  if status code >= 500 or timeout, will trigger retry
-		if client.config.AutoRetry && (timeout || serverError) {
+		if client.config.AutoRetry && (timeout || isServerError(httpResponse)) {
 			continue
 			continue
 		}
 		}
 		break
 		break
@@ -251,6 +263,30 @@ func NewClientWithAccessKey(regionId, accessKeyId, accessKeySecret string) (clie
 	return
 	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) {
 func (client *Client) ProcessCommonRequest(request *requests.CommonRequest) (response *responses.CommonResponse, err error) {
 	request.TransToAcsRequest()
 	request.TransToAcsRequest()
 	response = responses.NewCommonResponse()
 	response = responses.NewCommonResponse()

+ 88 - 45
sdk/client_test.go

@@ -28,7 +28,7 @@ import (
 	"testing"
 	"testing"
 )
 )
 
 
-var client, clientKeyPair, clientEcs, clientRoleArn *Client
+var client, clientKeyPair, clientEcs, clientRoleArn, clientSts *Client
 
 
 type TestConfig struct {
 type TestConfig struct {
 	AccessKeyId     string
 	AccessKeyId     string
@@ -36,6 +36,9 @@ type TestConfig struct {
 	PublicKeyId     string
 	PublicKeyId     string
 	PrivateKey      string
 	PrivateKey      string
 	RoleArn         string
 	RoleArn         string
+	StsToken        string
+	StsAk           string
+	StsSecret       string
 	ChildAK         string
 	ChildAK         string
 	ChildSecret     string
 	ChildSecret     string
 }
 }
@@ -81,8 +84,11 @@ func getConfigFromEnv() *TestConfig {
 		RoleArn:         os.Getenv("ROLE_ARN"),
 		RoleArn:         os.Getenv("ROLE_ARN"),
 		ChildAK:         os.Getenv("CHILD_AK"),
 		ChildAK:         os.Getenv("CHILD_AK"),
 		ChildSecret:     os.Getenv("CHILD_SECRET"),
 		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
 		return nil
 	} else {
 	} else {
 		return config
 		return config
@@ -95,11 +101,19 @@ func testSetup() {
 		testConfig = getConfigFromFile()
 		testConfig = getConfigFromFile()
 	}
 	}
 
 
-	clientConfig := NewConfig().WithHttpTransport(&http.Transport{
-		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
-	})
-
 	var err error
 	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{
 	credential := &credentials.BaseCredential{
 		AccessKeyId:     testConfig.AccessKeyId,
 		AccessKeyId:     testConfig.AccessKeyId,
 		AccessKeySecret: testConfig.AccessKeySecret,
 		AccessKeySecret: testConfig.AccessKeySecret,
@@ -108,18 +122,30 @@ func testSetup() {
 	if err != nil {
 	if err != nil {
 		panic(err)
 		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() {
 func testTearDown() {
@@ -297,7 +323,7 @@ func getFtTestRpcRequest() (request *requests.RpcRequest) {
 func getFtTestRpcRequestForEndpointLocation() (request *requests.RpcRequest) {
 func getFtTestRpcRequestForEndpointLocation() (request *requests.RpcRequest) {
 	request = &requests.RpcRequest{}
 	request = &requests.RpcRequest{}
 	request.InitWithApiInfo("Ft", "2016-01-01", "TestRpcApi", "ft", "openAPI")
 	request.InitWithApiInfo("Ft", "2016-01-01", "TestRpcApi", "ft", "openAPI")
-	request.RegionId = "cn-hangzhou"
+	request.RegionId = "ft-cn-hangzhou"
 	request.QueryParams["QueryParam"] = "QueryParamValue"
 	request.QueryParams["QueryParam"] = "QueryParamValue"
 	return
 	return
 }
 }
@@ -418,21 +444,21 @@ func TestRpcGetForLocationCache(t *testing.T) {
 	assert.Equal(t, "QueryParamValue", responseBean.Params["QueryParam"])
 	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) {
 /*func TestRpcGetForEcs(t *testing.T) {
 	//测试接口,想测试的时候,要替换掉singer_ecs_instance中对应的变量,并且还要提供一个mock服务
 	//测试接口,想测试的时候,要替换掉singer_ecs_instance中对应的变量,并且还要提供一个mock服务
@@ -461,12 +487,38 @@ func TestRpcGetForLocationCache(t *testing.T) {
 	assert.Equal(t, "QueryParamValue", responseBean.Params["QueryParam"])
 	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 := getFtTestRpcRequest()
 //	request.Method = requests.GET
 //	request.Method = requests.GET
 //
 //
 //	response := &responses.BaseResponse{}
 //	response := &responses.BaseResponse{}
-//	err := clientRoleArn.DoAction(request, response)
+//	err := clientSts.DoAction(request, response)
 //	assert.Nil(t, err)
 //	assert.Nil(t, err)
 //	assert.Equal(t, http.StatusOK, response.GetHttpStatus(), response.GetHttpContentString())
 //	assert.Equal(t, http.StatusOK, response.GetHttpStatus(), response.GetHttpContentString())
 //	assert.NotNil(t, response.GetHttpContentString())
 //	assert.NotNil(t, response.GetHttpContentString())
@@ -475,15 +527,6 @@ func TestRpcGetForLocationCache(t *testing.T) {
 //	json.Unmarshal([]byte(response.GetHttpContentString()), &responseBean)
 //	json.Unmarshal([]byte(response.GetHttpContentString()), &responseBean)
 //
 //
 //	assert.Equal(t, "QueryParamValue", responseBean.Params["QueryParam"])
 //	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) {
 func TestCommonRoaRequestForAcceptXML(t *testing.T) {

+ 1 - 1
sdk/config.go

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

+ 24 - 11
sdk/endpoints/location_resolver.go

@@ -16,6 +16,7 @@ package endpoints
 import (
 import (
 	"encoding/json"
 	"encoding/json"
 	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
 	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
+	"sync"
 	"time"
 	"time"
 )
 )
 
 
@@ -23,8 +24,15 @@ const (
 	EndpointCacheExpireTime = 3600 //Seconds
 	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 {
 type LocationResolver struct {
 }
 }
@@ -37,8 +45,8 @@ func (resolver *LocationResolver) TryResolve(param *ResolveParam) (endpoint stri
 
 
 	//get from cache
 	//get from cache
 	cacheKey := param.Product + "#" + param.RegionId
 	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
 		support = true
 		return
 		return
 	}
 	}
@@ -53,14 +61,13 @@ func (resolver *LocationResolver) TryResolve(param *ResolveParam) (endpoint stri
 
 
 	getEndpointRequest.QueryParams["Id"] = param.RegionId
 	getEndpointRequest.QueryParams["Id"] = param.RegionId
 	getEndpointRequest.QueryParams["ServiceCode"] = param.LocationProduct
 	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 {
 	} else {
 		getEndpointRequest.QueryParams["Type"] = "openAPI"
 		getEndpointRequest.QueryParams["Type"] = "openAPI"
 	}
 	}
 
 
 	response, err := param.CommonApi(getEndpointRequest)
 	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
 	var getEndpointResponse GetEndpointResponse
 	if !response.IsSuccess() {
 	if !response.IsSuccess() {
 		support = false
 		support = false
@@ -78,8 +85,12 @@ func (resolver *LocationResolver) TryResolve(param *ResolveParam) (endpoint stri
 	}
 	}
 	if len(getEndpointResponse.Endpoints.Endpoint[0].Endpoint) > 0 {
 	if len(getEndpointResponse.Endpoints.Endpoint[0].Endpoint) > 0 {
 		endpoint = getEndpointResponse.Endpoints.Endpoint[0].Endpoint
 		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
 		support = true
 		return
 		return
 	}
 	}
@@ -89,10 +100,12 @@ func (resolver *LocationResolver) TryResolve(param *ResolveParam) (endpoint stri
 }
 }
 
 
 func CheckCacheIsExpire(cacheKey string) bool {
 func CheckCacheIsExpire(cacheKey string) bool {
-	lastClearTime := lastClearTimePerProduct[cacheKey]
+	lastClearTime := lastClearTimePerProduct.cache[cacheKey]
 	if lastClearTime <= 0 {
 	if lastClearTime <= 0 {
 		lastClearTime = time.Now().Unix()
 		lastClearTime = time.Now().Unix()
-		lastClearTimePerProduct[cacheKey] = lastClearTime
+		lastClearTimePerProduct.Lock()
+		lastClearTimePerProduct.cache[cacheKey] = lastClearTime
+		lastClearTimePerProduct.Unlock()
 	}
 	}
 
 
 	now := time.Now().Unix()
 	now := time.Now().Unix()

+ 8 - 8
sdk/endpoints/resolver.go

@@ -44,8 +44,8 @@ func Resolve(param *ResolveParam) (endpoint string, err error) {
 	}
 	}
 
 
 	// not support
 	// 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
 	return
 }
 }
 
 
@@ -61,12 +61,12 @@ func getAllResolvers() []Resolver {
 }
 }
 
 
 type ResolveParam struct {
 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 {
 func (param *ResolveParam) String() string {

+ 23 - 13
sdk/errors/client_error.go

@@ -20,23 +20,29 @@ const (
 	DefaultClientErrorStatus = 400
 	DefaultClientErrorStatus = 400
 	DefaultClientErrorCode   = "SDK.ClientError"
 	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"
 	AsyncFunctionNotEnabledCode    = "SDK.AsyncFunctionNotEnabled"
 	AsyncFunctionNotEnabledMessage = "Async function is not enabled in client, please invoke 'client.EnableAsync' function"
 	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 {
 type ClientError struct {
@@ -54,11 +60,11 @@ func NewClientError(errorCode, message string, originErr error) Error {
 }
 }
 
 
 func (err *ClientError) Error() string {
 func (err *ClientError) Error() string {
+	clientErrMsg := fmt.Sprintf("[%s] %s", err.errorCode, err.message)
 	if err.originError != nil {
 	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 {
 func (err *ClientError) OriginError() error {
@@ -80,3 +86,7 @@ func (err *ClientError) ErrorCode() string {
 func (err *ClientError) Message() string {
 func (err *ClientError) Message() string {
 	return err.message
 	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:
 		case Body:
 			request.addFormParam(name, value)
 			request.addFormParam(name, value)
 		default:
 		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
 	return

+ 3 - 3
sdk/requests/common_request.go

@@ -31,13 +31,13 @@ func NewCommonRequest() (request *CommonRequest) {
 
 
 func (request *CommonRequest) TransToAcsRequest() {
 func (request *CommonRequest) TransToAcsRequest() {
 	if len(request.Version) == 0 {
 	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 {
 	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 {
 	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 {
 	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())
 	assert.True(t, integer.hasValue())
 	value, err := integer.getValue()
 	value, err := integer.getValue()
 	assert.Nil(t, err)
 	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) {
 func TestNewBoolean(t *testing.T) {
@@ -18,7 +21,10 @@ func TestNewBoolean(t *testing.T) {
 	assert.True(t, boolean.hasValue())
 	assert.True(t, boolean.hasValue())
 	value, err := boolean.getValue()
 	value, err := boolean.getValue()
 	assert.Nil(t, err)
 	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) {
 func TestNewFloat(t *testing.T) {
@@ -26,5 +32,8 @@ func TestNewFloat(t *testing.T) {
 	assert.True(t, float.hasValue())
 	assert.True(t, float.hasValue())
 	value, err := float.getValue()
 	value, err := float.getValue()
 	assert.Nil(t, err)
 	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)
 	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) {
 func getJsonBytes() ([]byte, error) {
 	from := &From{
 	from := &From{
 		StrToStr:            "demo string",
 		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())
 		err = errors.NewServerError(response.GetHttpStatus(), response.GetOriginHttpResponse().Status, response.GetHttpContentString())
 		return
 		return
 	}
 	}
+	if _, isCommonResponse := response.(CommonResponse); isCommonResponse {
+		// common response need not unmarshal
+		return
+	}
 	if strings.ToUpper(format) == "JSON" {
 	if strings.ToUpper(format) == "JSON" {
 		initJsonParserOnce()
 		initJsonParserOnce()
 		err = jsonParser.Unmarshal(response.GetHttpContentBytes(), response)
 		err = jsonParser.Unmarshal(response.GetHttpContentBytes(), response)
+		if err != nil {
+			err = errors.NewClientError(errors.JsonUnmarshalErrorCode, errors.JsonUnmarshalErrorMessage, err)
+		}
 	} else if strings.ToUpper(format) == "XML" {
 	} else if strings.ToUpper(format) == "XML" {
 		err = xml.Unmarshal(response.GetHttpContentBytes(), response)
 		err = xml.Unmarshal(response.GetHttpContentBytes(), response)
 	}
 	}

+ 3 - 0
sdk/utils/utils.go

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

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

@@ -124,197 +124,197 @@ type functionCaller struct {
 func newFunctionCaller() *functionCaller {
 func newFunctionCaller() *functionCaller {
 	caller := &functionCaller{}
 	caller := &functionCaller{}
 	caller.functionTable = map[string]functionEntry{
 	caller.functionTable = map[string]functionEntry{
-		"length": functionEntry{
+		"length": {
 			name: "length",
 			name: "length",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpString, jpArray, jpObject}},
+				{types: []jpType{jpString, jpArray, jpObject}},
 			},
 			},
 			handler: jpfLength,
 			handler: jpfLength,
 		},
 		},
-		"starts_with": functionEntry{
+		"starts_with": {
 			name: "starts_with",
 			name: "starts_with",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpString}},
-				argSpec{types: []jpType{jpString}},
+				{types: []jpType{jpString}},
+				{types: []jpType{jpString}},
 			},
 			},
 			handler: jpfStartsWith,
 			handler: jpfStartsWith,
 		},
 		},
-		"abs": functionEntry{
+		"abs": {
 			name: "abs",
 			name: "abs",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpNumber}},
+				{types: []jpType{jpNumber}},
 			},
 			},
 			handler: jpfAbs,
 			handler: jpfAbs,
 		},
 		},
-		"avg": functionEntry{
+		"avg": {
 			name: "avg",
 			name: "avg",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArrayNumber}},
+				{types: []jpType{jpArrayNumber}},
 			},
 			},
 			handler: jpfAvg,
 			handler: jpfAvg,
 		},
 		},
-		"ceil": functionEntry{
+		"ceil": {
 			name: "ceil",
 			name: "ceil",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpNumber}},
+				{types: []jpType{jpNumber}},
 			},
 			},
 			handler: jpfCeil,
 			handler: jpfCeil,
 		},
 		},
-		"contains": functionEntry{
+		"contains": {
 			name: "contains",
 			name: "contains",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArray, jpString}},
-				argSpec{types: []jpType{jpAny}},
+				{types: []jpType{jpArray, jpString}},
+				{types: []jpType{jpAny}},
 			},
 			},
 			handler: jpfContains,
 			handler: jpfContains,
 		},
 		},
-		"ends_with": functionEntry{
+		"ends_with": {
 			name: "ends_with",
 			name: "ends_with",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpString}},
-				argSpec{types: []jpType{jpString}},
+				{types: []jpType{jpString}},
+				{types: []jpType{jpString}},
 			},
 			},
 			handler: jpfEndsWith,
 			handler: jpfEndsWith,
 		},
 		},
-		"floor": functionEntry{
+		"floor": {
 			name: "floor",
 			name: "floor",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpNumber}},
+				{types: []jpType{jpNumber}},
 			},
 			},
 			handler: jpfFloor,
 			handler: jpfFloor,
 		},
 		},
-		"map": functionEntry{
+		"map": {
 			name: "amp",
 			name: "amp",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpExpref}},
-				argSpec{types: []jpType{jpArray}},
+				{types: []jpType{jpExpref}},
+				{types: []jpType{jpArray}},
 			},
 			},
 			handler:   jpfMap,
 			handler:   jpfMap,
 			hasExpRef: true,
 			hasExpRef: true,
 		},
 		},
-		"max": functionEntry{
+		"max": {
 			name: "max",
 			name: "max",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArrayNumber, jpArrayString}},
+				{types: []jpType{jpArrayNumber, jpArrayString}},
 			},
 			},
 			handler: jpfMax,
 			handler: jpfMax,
 		},
 		},
-		"merge": functionEntry{
+		"merge": {
 			name: "merge",
 			name: "merge",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpObject}, variadic: true},
+				{types: []jpType{jpObject}, variadic: true},
 			},
 			},
 			handler: jpfMerge,
 			handler: jpfMerge,
 		},
 		},
-		"max_by": functionEntry{
+		"max_by": {
 			name: "max_by",
 			name: "max_by",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArray}},
-				argSpec{types: []jpType{jpExpref}},
+				{types: []jpType{jpArray}},
+				{types: []jpType{jpExpref}},
 			},
 			},
 			handler:   jpfMaxBy,
 			handler:   jpfMaxBy,
 			hasExpRef: true,
 			hasExpRef: true,
 		},
 		},
-		"sum": functionEntry{
+		"sum": {
 			name: "sum",
 			name: "sum",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArrayNumber}},
+				{types: []jpType{jpArrayNumber}},
 			},
 			},
 			handler: jpfSum,
 			handler: jpfSum,
 		},
 		},
-		"min": functionEntry{
+		"min": {
 			name: "min",
 			name: "min",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArrayNumber, jpArrayString}},
+				{types: []jpType{jpArrayNumber, jpArrayString}},
 			},
 			},
 			handler: jpfMin,
 			handler: jpfMin,
 		},
 		},
-		"min_by": functionEntry{
+		"min_by": {
 			name: "min_by",
 			name: "min_by",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArray}},
-				argSpec{types: []jpType{jpExpref}},
+				{types: []jpType{jpArray}},
+				{types: []jpType{jpExpref}},
 			},
 			},
 			handler:   jpfMinBy,
 			handler:   jpfMinBy,
 			hasExpRef: true,
 			hasExpRef: true,
 		},
 		},
-		"type": functionEntry{
+		"type": {
 			name: "type",
 			name: "type",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpAny}},
+				{types: []jpType{jpAny}},
 			},
 			},
 			handler: jpfType,
 			handler: jpfType,
 		},
 		},
-		"keys": functionEntry{
+		"keys": {
 			name: "keys",
 			name: "keys",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpObject}},
+				{types: []jpType{jpObject}},
 			},
 			},
 			handler: jpfKeys,
 			handler: jpfKeys,
 		},
 		},
-		"values": functionEntry{
+		"values": {
 			name: "values",
 			name: "values",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpObject}},
+				{types: []jpType{jpObject}},
 			},
 			},
 			handler: jpfValues,
 			handler: jpfValues,
 		},
 		},
-		"sort": functionEntry{
+		"sort": {
 			name: "sort",
 			name: "sort",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArrayString, jpArrayNumber}},
+				{types: []jpType{jpArrayString, jpArrayNumber}},
 			},
 			},
 			handler: jpfSort,
 			handler: jpfSort,
 		},
 		},
-		"sort_by": functionEntry{
+		"sort_by": {
 			name: "sort_by",
 			name: "sort_by",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArray}},
-				argSpec{types: []jpType{jpExpref}},
+				{types: []jpType{jpArray}},
+				{types: []jpType{jpExpref}},
 			},
 			},
 			handler:   jpfSortBy,
 			handler:   jpfSortBy,
 			hasExpRef: true,
 			hasExpRef: true,
 		},
 		},
-		"join": functionEntry{
+		"join": {
 			name: "join",
 			name: "join",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpString}},
-				argSpec{types: []jpType{jpArrayString}},
+				{types: []jpType{jpString}},
+				{types: []jpType{jpArrayString}},
 			},
 			},
 			handler: jpfJoin,
 			handler: jpfJoin,
 		},
 		},
-		"reverse": functionEntry{
+		"reverse": {
 			name: "reverse",
 			name: "reverse",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpArray, jpString}},
+				{types: []jpType{jpArray, jpString}},
 			},
 			},
 			handler: jpfReverse,
 			handler: jpfReverse,
 		},
 		},
-		"to_array": functionEntry{
+		"to_array": {
 			name: "to_array",
 			name: "to_array",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpAny}},
+				{types: []jpType{jpAny}},
 			},
 			},
 			handler: jpfToArray,
 			handler: jpfToArray,
 		},
 		},
-		"to_string": functionEntry{
+		"to_string": {
 			name: "to_string",
 			name: "to_string",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpAny}},
+				{types: []jpType{jpAny}},
 			},
 			},
 			handler: jpfToString,
 			handler: jpfToString,
 		},
 		},
-		"to_number": functionEntry{
+		"to_number": {
 			name: "to_number",
 			name: "to_number",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpAny}},
+				{types: []jpType{jpAny}},
 			},
 			},
 			handler: jpfToNumber,
 			handler: jpfToNumber,
 		},
 		},
-		"not_null": functionEntry{
+		"not_null": {
 			name: "not_null",
 			name: "not_null",
 			arguments: []argSpec{
 			arguments: []argSpec{
-				argSpec{types: []jpType{jpAny}, variadic: true},
+				{types: []jpType{jpAny}, variadic: true},
 			},
 			},
 			handler: jpfNotNull,
 			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) {
 func TestCanSupportStructWithSliceAll(t *testing.T) {
 	assert := assert.New(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)
 	result, err := Search("B[].Foo", data)
 	assert.Nil(err)
 	assert.Nil(err)
 	assert.Equal([]interface{}{"f1", "correct"}, result)
 	assert.Equal([]interface{}{"f1", "correct"}, result)
@@ -77,7 +77,7 @@ func TestCanSupportStructWithSliceAll(t *testing.T) {
 
 
 func TestCanSupportStructWithSlicingExpression(t *testing.T) {
 func TestCanSupportStructWithSlicingExpression(t *testing.T) {
 	assert := assert.New(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)
 	result, err := Search("B[:].Foo", data)
 	assert.Nil(err)
 	assert.Nil(err)
 	assert.Equal([]interface{}{"f1", "correct"}, result)
 	assert.Equal([]interface{}{"f1", "correct"}, result)
@@ -85,7 +85,7 @@ func TestCanSupportStructWithSlicingExpression(t *testing.T) {
 
 
 func TestCanSupportStructWithFilterProjection(t *testing.T) {
 func TestCanSupportStructWithFilterProjection(t *testing.T) {
 	assert := assert.New(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)
 	result, err := Search("B[? `true` ].Foo", data)
 	assert.Nil(err)
 	assert.Nil(err)
 	assert.Equal([]interface{}{"f1", "correct"}, result)
 	assert.Equal([]interface{}{"f1", "correct"}, result)
@@ -93,7 +93,7 @@ func TestCanSupportStructWithFilterProjection(t *testing.T) {
 
 
 func TestCanSupportStructWithSlice(t *testing.T) {
 func TestCanSupportStructWithSlice(t *testing.T) {
 	assert := assert.New(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)
 	result, err := Search("B[-1].Foo", data)
 	assert.Nil(err)
 	assert.Nil(err)
 	assert.Equal("correct", result)
 	assert.Equal("correct", result)
@@ -109,7 +109,7 @@ func TestCanSupportStructWithOrExpressions(t *testing.T) {
 
 
 func TestCanSupportStructWithSlicePointer(t *testing.T) {
 func TestCanSupportStructWithSlicePointer(t *testing.T) {
 	assert := assert.New(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)
 	result, err := Search("C[-1].Foo", data)
 	assert.Nil(err)
 	assert.Nil(err)
 	assert.Equal("correct", result)
 	assert.Equal("correct", result)
@@ -128,7 +128,7 @@ func TestWillAutomaticallyCapitalizeFieldNames(t *testing.T) {
 
 
 func TestCanSupportStructWithSliceLowerCased(t *testing.T) {
 func TestCanSupportStructWithSliceLowerCased(t *testing.T) {
 	assert := assert.New(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)
 	result, err := Search("b[-1].foo", data)
 	assert.Nil(err)
 	assert.Nil(err)
 	assert.Equal("correct", result)
 	assert.Equal("correct", result)

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

@@ -11,63 +11,63 @@ var lexingTests = []struct {
 	expression string
 	expression string
 	expected   []token
 	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
 	// 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
 	// 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.
 	// Combinations of tokens.
 	{"foo.bar", []token{
 	{"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{
 	{"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{
 	{"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:
 	case tFlatten:
 		left := ASTNode{
 		left := ASTNode{
 			nodeType: ASTFlatten,
 			nodeType: ASTFlatten,
-			children: []ASTNode{ASTNode{nodeType: ASTIdentity}},
+			children: []ASTNode{{nodeType: ASTIdentity}},
 		}
 		}
 		right, err := p.parseProjectionRHS(bindingPowers[tFlatten])
 		right, err := p.parseProjectionRHS(bindingPowers[tFlatten])
 		if err != nil {
 		if err != nil {
@@ -378,7 +378,7 @@ func (p *Parser) nud(token token) (ASTNode, error) {
 			}
 			}
 			return ASTNode{
 			return ASTNode{
 				nodeType: ASTProjection,
 				nodeType: ASTProjection,
-				children: []ASTNode{ASTNode{nodeType: ASTIdentity}, right},
+				children: []ASTNode{{nodeType: ASTIdentity}, right},
 			}, nil
 			}, nil
 		} else {
 		} else {
 			return p.parseMultiSelectList()
 			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[2] = 2
 	input[3] = 3
 	input[3] = 3
 	input[4] = 4
 	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.Nil(err)
 	assert.Equal(input[:3], result)
 	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)
 		Return(nil)
 
 
 	expectedCalls := []*Call{
 	expectedCalls := []*Call{
-		&Call{
+		{
 			Parent:          &mockedService.Mock,
 			Parent:          &mockedService.Mock,
 			Method:          "TheExampleMethod",
 			Method:          "TheExampleMethod",
 			Arguments:       []interface{}{1, 2, 3},
 			Arguments:       []interface{}{1, 2, 3},
 			ReturnArguments: []interface{}{0},
 			ReturnArguments: []interface{}{0},
 		},
 		},
-		&Call{
+		{
 			Parent:          &mockedService.Mock,
 			Parent:          &mockedService.Mock,
 			Method:          "TheExampleMethod3",
 			Method:          "TheExampleMethod3",
 			Arguments:       []interface{}{AnythingOfType("*mock.ExampleType")},
 			Arguments:       []interface{}{AnythingOfType("*mock.ExampleType")},
@@ -1342,7 +1342,7 @@ func TestAfterTotalWaitTimeWhileExecution(t *testing.T) {
 	elapsedTime := end.Sub(start)
 	elapsedTime := end.Sub(start)
 	assert.True(t, elapsedTime > waitMs, fmt.Sprintf("Total elapsed time:%v should be atleast greater than %v", elapsedTime, waitMs))
 	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))
 	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")
 		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)
 		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]"
 	expected = "map[ts.1:1 ts.2:2 ts.3:3]"
 	if s != expected {
 	if s != expected {
 		t.Errorf("Sorted keys mismatch 4:\n  %v %v", s, expected)
 		t.Errorf("Sorted keys mismatch 4:\n  %v %v", s, expected)
 	}
 	}
 
 
 	if !spew.UnsafeDisabled {
 	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]"
 		expected = "map[ts.1:1 ts.2:2 ts.3:3]"
 		if s != expected {
 		if s != expected {
 			t.Errorf("Sorted keys mismatch 5:\n  %v %v", 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{}{}
 	m.bJunk = map[string]struct{}{}
 	if m.IsJunk != nil {
 	if m.IsJunk != nil {
 		junk := m.bJunk
 		junk := m.bJunk
-		for s, _ := range b2j {
+		for s := range b2j {
 			if m.IsJunk(s) {
 			if m.IsJunk(s) {
 				junk[s] = struct{}{}
 				junk[s] = struct{}{}
 			}
 			}
 		}
 		}
-		for s, _ := range junk {
+		for s := range junk {
 			delete(b2j, s)
 			delete(b2j, s)
 		}
 		}
 	}
 	}
@@ -181,7 +181,7 @@ func (m *SequenceMatcher) chainB() {
 				popular[s] = struct{}{}
 				popular[s] = struct{}{}
 			}
 			}
 		}
 		}
-		for s, _ := range popular {
+		for s := range popular {
 			delete(b2j, s)
 			delete(b2j, s)
 		}
 		}
 	}
 	}
@@ -416,7 +416,7 @@ func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode {
 	}
 	}
 	codes := m.GetOpCodes()
 	codes := m.GetOpCodes()
 	if len(codes) == 0 {
 	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.
 	// Fixup leading and trailing groups if they show no changes.
 	if codes[0].Tag == 'e' {
 	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)),
 	sm = NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)),
 		splitChars(rep("a", 44)+rep("b", 40)+rep(" ", 20)), false, isJunk)
 		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 {
 	isJunk = func(s string) bool {
 		return s == " " || s == "b"
 		return s == " " || s == "b"
 	}
 	}
 	sm = NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)),
 	sm = NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)),
 		splitChars(rep("a", 44)+rep("b", 40)+rep(" ", 20)), false, isJunk)
 		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) {
 func TestSFBugsRatioForNullSeqn(t *testing.T) {