Skip to content

Commit

Permalink
add state waiter and fix all acceptance tests (#5)
Browse files Browse the repository at this point in the history
* initial commit

* set default log level to warn level

* update version

* fix test filename

* fix test set 687

* fix test set 302

* fix test set 687

* fix backend type error and support array of request

* fix test set 1839

* fix test set 1840

* fix test set 1839

* fix test set 1839

* fix test set 1839

* add StateWaiter
  • Loading branch information
yufeiminds authored Oct 12, 2018
1 parent 6385fcd commit 175ad0c
Show file tree
Hide file tree
Showing 25 changed files with 477 additions and 25 deletions.
1 change: 0 additions & 1 deletion examples/retry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ To enable retry for client or request.
```go
export UCLOUD_PUBLIC_KEY="your public key"
export UCLOUD_PRIVATE_KEY="your private key"
export UCLOUD_REGION="cn-bj2"
export UCLOUD_PROJECT_ID="your project id"
```

Expand Down
7 changes: 5 additions & 2 deletions examples/retry/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@ package main
import (
"os"

"github.com/ucloud/ucloud-sdk-go/services/ulb"
"github.com/ucloud/ucloud-sdk-go/ucloud"
"github.com/ucloud/ucloud-sdk-go/ucloud/auth"
"github.com/ucloud/ucloud-sdk-go/ucloud/log"

"github.com/ucloud/ucloud-sdk-go/services/ulb"
)

const region = "cn-bj2"

func main() {
cfg := ucloud.NewConfig()
cfg.LogLevel = log.DebugLevel
cfg.Region = os.Getenv("UCLOUD_REGION")
cfg.Region = region
cfg.ProjectId = os.Getenv("UCLOUD_PROJECT_ID")

credential := auth.NewCredential()
Expand Down
3 changes: 2 additions & 1 deletion examples/uhost/main.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package main

import (
"github.com/ucloud/ucloud-sdk-go/ucloud"

"github.com/ucloud/ucloud-sdk-go/services/uhost"
"github.com/ucloud/ucloud-sdk-go/services/unet"
"github.com/ucloud/ucloud-sdk-go/ucloud"
)

var uhostClient *uhost.UHostClient
Expand Down
19 changes: 19 additions & 0 deletions examples/wait/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# UCloud SDK Wait Example

## What is the goal

To enable state waiter to wait remote resource is completed.

## Setup Environment

```go
export UCLOUD_PUBLIC_KEY="your public key"
export UCLOUD_PRIVATE_KEY="your private key"
export UCLOUD_PROJECT_ID="your project id"
```

## How to run

```sh
go run main.go
```
101 changes: 101 additions & 0 deletions examples/wait/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package main

import (
"os"
"time"

"github.com/ucloud/ucloud-sdk-go/ucloud"
"github.com/ucloud/ucloud-sdk-go/ucloud/auth"
"github.com/ucloud/ucloud-sdk-go/ucloud/log"

"github.com/ucloud/ucloud-sdk-go/ucloud/helpers/waiter"

"github.com/ucloud/ucloud-sdk-go/services/uhost"
)

const region = "cn-bj2"
const zone = "cn-bj2-05"
const imageID = "uimage-kg0w4u"

var uhostClient *uhost.UHostClient

func init() {
cfg := ucloud.NewConfig()
cfg.LogLevel = log.DebugLevel
cfg.Region = region
cfg.ProjectId = os.Getenv("UCLOUD_PROJECT_ID")

credential := auth.NewCredential()
credential.PrivateKey = os.Getenv("UCLOUD_PRIVATE_KEY")
credential.PublicKey = os.Getenv("UCLOUD_PUBLIC_KEY")

uhostClient = uhost.NewClient(&cfg, &credential)

log.Info("setup clients ...")
}

func main() {
uhostID, err := createUHost("sdk-example-wait")
if err != nil {
log.Error(err)
}

w := waiter.StateWaiter{
Pending: []string{"pending"},
Target: []string{"avaliable"},
Refresh: func() (interface{}, string, error) {
inst, err := describeUHostByID(uhostID)
if err != nil {
return nil, "", err
}

if inst == nil || inst.State != "Running" {
return nil, "pending", nil
}

return inst, "avaliable", nil
},
Timeout: 5 * time.Minute,
}

if resp, err := w.Wait(); err != nil {
log.Error(err)
} else {
log.Infof("%#v", resp)
}
}

func describeUHostByID(uhostID string) (*uhost.UHostInstanceSet, error) {
req := uhostClient.NewDescribeUHostInstanceRequest()
req.UHostIds = []string{uhostID}

resp, err := uhostClient.DescribeUHostInstance(req)
if err != nil {
return nil, err
}
if len(resp.UHostSet) < 1 {
return nil, nil
}

return &resp.UHostSet[0], nil
}

func createUHost(name string) (string, error) {
req := uhostClient.NewCreateUHostInstanceRequest()
req.Name = ucloud.String(name)
req.Zone = ucloud.String(zone) // TODO: use random zone
req.ImageId = ucloud.String(imageID) // TODO: use random image
req.LoginMode = ucloud.String("Password")
req.Password = ucloud.String("somePassword_")
req.ChargeType = ucloud.String("Dynamic")
req.CPU = ucloud.Int(1)
req.Memory = ucloud.Int(1024)
req.Tag = ucloud.String("sdk-example")

resp, err := uhostClient.CreateUHostInstance(req)
if err != nil {
return "", err
}

return resp.UHostIds[0], nil
}
5 changes: 5 additions & 0 deletions internal/services/umon/describe_resource_metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ type DescribeResourceMetricResponse struct {
// NewDescribeResourceMetricRequest will create request of DescribeResourceMetric action.
func (c *UMonClient) NewDescribeResourceMetricRequest() *DescribeResourceMetricRequest {
req := &DescribeResourceMetricRequest{}

// setup request with client config
c.client.SetupRequest(req)

// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}

Expand Down
6 changes: 3 additions & 3 deletions internal/services/umon/types_metric_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ type MetricInfo struct {
SupportAlarm string

// 告警设置范围
AlarmRange string
AlarmRange interface{} // Backend Bug: backend use dynamic type, object or string

// 数据上报频率
Frequency string
// 仅限内部使用
Frequency int

// 比较参数,可选GE,LE
CompareOption []string
Expand Down
5 changes: 5 additions & 0 deletions internal/services/unet/describe_security_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ type DescribeSecurityGroupResponse struct {
// NewDescribeSecurityGroupRequest will create request of DescribeSecurityGroup action.
func (c *UNetClient) NewDescribeSecurityGroupRequest() *DescribeSecurityGroupRequest {
req := &DescribeSecurityGroupRequest{}

// setup request with client config
c.client.SetupRequest(req)

// setup retryable with default retry policy (retry for non-create action and common error)
req.SetRetryable(true)
return req
}

Expand Down
2 changes: 1 addition & 1 deletion internal/services/unet/types_security_group_rule_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type SecurityGroupRuleSet struct {
SrcIP string

// 优先级
Priority int
Priority string

// 协议类型
ProtocolType string
Expand Down
4 changes: 2 additions & 2 deletions internal/services/unet/types_unet_security_group_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ type UnetSecurityGroupSet struct {
GroupName string

// 防火墙组创建时间,格式为Unix Timestamp
CreateTime string
CreateTime int

// 防火墙组类型,枚举值为: 0:用户自定义防火墙; 1:默认Web防火墙; 2:默认非Web防火墙
Type string
Type int

// 防火墙组中的规则表,参见 SecurityGroupRuleSet
Rule []SecurityGroupRuleSet
Expand Down
25 changes: 18 additions & 7 deletions internal/utest/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ func GetValue(obj interface{}, path string) (interface{}, error) {
}

// SetReqValue will set value into pointer referenced or slice
func SetReqValue(addr interface{}, field string, value interface{}) error {
func SetReqValue(addr interface{}, field string, values ...interface{}) error {
if len(values) == 0 {
return errors.Errorf("no values to be set")
}

rv := reflect.ValueOf(addr)
if rv.IsValid() == false {
return errors.Errorf("struct is invalid")
Expand Down Expand Up @@ -54,16 +58,23 @@ func SetReqValue(addr interface{}, field string, value interface{}) error {
return errors.Errorf("cannot set %s, field cannot be set", field)
}

s, _ := toString(value)
v, err := convertValueWithType(rv.Type().Elem(), s)
if err != nil {
return err
rValues := []reflect.Value{}
for _, value := range values {
s, _ := toString(value)
v, err := convertValueWithType(rv.Type().Elem(), s)
if err != nil {
return err
}
rValues = append(rValues, v)
}

if rv.Kind() == reflect.Ptr {
rv.Set(v)
rv.Set(rValues[0])
} else if rv.Kind() == reflect.Slice {
rv.Set(reflect.Append(rv, v.Elem()))
rv.Set(reflect.MakeSlice(rv.Type(), 0, 0))
for _, willSet := range rValues {
rv.Set(reflect.Append(rv, willSet.Elem()))
}
}

return nil
Expand Down
5 changes: 5 additions & 0 deletions internal/utest/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,9 @@ func TestSetReqValue(t *testing.T) {
if testObj.IPs[0] != "192.168.0.1" {
t.Errorf("SetReqValue() = %#v, want %v", testObj.IPs[0], "192.168.0.1")
}

SetReqValue(&testObj, "IPs", "192.168.0.1", "192.168.0.2")
if testObj.IPs[0] != "192.168.0.1" || testObj.IPs[1] != "192.168.0.2" {
t.Errorf("SetReqValue() = %#v, want %v", testObj.IPs, []string{"192.168.0.1", "192.168.0.2"})
}
}
4 changes: 2 additions & 2 deletions services/unet/types_resource_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ type ResourceSet struct {
// 绑定资源的资源类型
ResourceType string

// 状态
Status string
// 资源状态
Status int

// 业务组
Tag string
Expand Down
2 changes: 1 addition & 1 deletion services/vpc/types_resource_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type ResourceInfo struct {
// 资源id
ResourceId string

// 创建时间
// 资源类型
ResourceType string

// ip地址
Expand Down
1 change: 1 addition & 0 deletions tests/set_1840_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func testSet1840CreateUHostInstance00(ctx *utest.TestContext) {

ctx.NoError(utest.SetReqValue(req, "TimemachineFeature", "no"))
ctx.NoError(utest.SetReqValue(req, "HotplugFeature", "false"))
ctx.NoError(utest.SetReqValue(req, "DiskSpace", 20))

ctx.NoError(utest.SetReqValue(req, "GPU", 0)) // TODO: check

Expand Down
2 changes: 1 addition & 1 deletion tests/set_333_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ func testSet333DescribeUHostInstance17(ctx *utest.TestContext) {

ctx.NoError(utest.SetReqValue(req, "Region", ctx.GetVar("Region")))

ctx.NoError(utest.SetReqValue(req, "UHostIds", []string{ctx.GetVar("hostId").(string), ctx.GetVar("hostId2").(string)})) // TODO: check
ctx.NoError(utest.SetReqValue(req, "UHostIds", ctx.GetVar("hostId"), ctx.GetVar("hostId2")))

testCase := utest.TestCase{
Invoker: func() (interface{}, error) {
Expand Down
6 changes: 6 additions & 0 deletions tests/set_687_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ func testSet687CreateVPC04(ctx *utest.TestContext) {
ctx.NoError(utest.SetReqValue(req, "Region", ctx.GetVar("Region")))
ctx.NoError(utest.SetReqValue(req, "Name", "vpc_2"))
ctx.NoError(utest.SetReqValue(req, "Network", "192.168.16.0/20"))
ctx.NoError(utest.SetReqValue(req, "ProjectId", ctx.Must(utest.SearchValue(ctx.GetVar("project_list"), "IsDefault", "true", "ProjectId"))))

testCase := utest.TestCase{
Invoker: func() (interface{}, error) {
Expand All @@ -202,6 +203,7 @@ func testSet687CreateSubnet05(ctx *utest.TestContext) {
req := vpcClient.NewCreateSubnetRequest()

ctx.NoError(utest.SetReqValue(req, "Region", ctx.GetVar("Region")))
ctx.NoError(utest.SetReqValue(req, "ProjectId", ctx.Must(utest.SearchValue(ctx.GetVar("project_list"), "IsDefault", "true", "ProjectId"))))

ctx.NoError(utest.SetReqValue(req, "VPCId", ctx.GetVar("VPCId_2")))
ctx.NoError(utest.SetReqValue(req, "Subnet", "192.168.17.0"))
Expand Down Expand Up @@ -234,6 +236,7 @@ func testSet687CreateSubnet06(ctx *utest.TestContext) {
req := vpcClient.NewCreateSubnetRequest()

ctx.NoError(utest.SetReqValue(req, "Region", ctx.GetVar("Region")))
ctx.NoError(utest.SetReqValue(req, "ProjectId", ctx.Must(utest.SearchValue(ctx.GetVar("project_list"), "IsDefault", "true", "ProjectId"))))

ctx.NoError(utest.SetReqValue(req, "VPCId", ctx.GetVar("VPCId_2")))
ctx.NoError(utest.SetReqValue(req, "Subnet", "192.168.18.0"))
Expand Down Expand Up @@ -465,6 +468,7 @@ func testSet687DeleteSubnet13(ctx *utest.TestContext) {
req := vpcClient.NewDeleteSubnetRequest()

ctx.NoError(utest.SetReqValue(req, "Region", ctx.GetVar("Region")))
ctx.NoError(utest.SetReqValue(req, "ProjectId", ctx.Must(utest.SearchValue(ctx.GetVar("project_list"), "IsDefault", "true", "ProjectId"))))

ctx.NoError(utest.SetReqValue(req, "SubnetId", ctx.GetVar("SubnetId_2_1")))

Expand Down Expand Up @@ -493,6 +497,7 @@ func testSet687DeleteSubnet14(ctx *utest.TestContext) {
req := vpcClient.NewDeleteSubnetRequest()

ctx.NoError(utest.SetReqValue(req, "Region", ctx.GetVar("Region")))
ctx.NoError(utest.SetReqValue(req, "ProjectId", ctx.Must(utest.SearchValue(ctx.GetVar("project_list"), "IsDefault", "true", "ProjectId"))))

ctx.NoError(utest.SetReqValue(req, "SubnetId", ctx.GetVar("SubnetId_2_2")))

Expand Down Expand Up @@ -695,6 +700,7 @@ func testSet687DeleteVPC21(ctx *utest.TestContext) {
req := vpcClient.NewDeleteVPCRequest()

ctx.NoError(utest.SetReqValue(req, "Region", ctx.GetVar("Region")))
ctx.NoError(utest.SetReqValue(req, "ProjectId", ctx.Must(utest.SearchValue(ctx.GetVar("project_list"), "IsDefault", "true", "ProjectId"))))

ctx.NoError(utest.SetReqValue(req, "VPCId", ctx.GetVar("VPCId_2")))

Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion ucloud/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (c *Client) InvokeAction(action string, req request.Common, resp response.C
httpResp, err = handler(c, httpReq, httpResp, err)
}

err = c.UnmarshalHTTPReponse(httpResp, resp)
err = c.unmarshalHTTPReponse(httpResp, resp)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 175ad0c

Please sign in to comment.