Skip to content

Commit

Permalink
LIST returns empty array (#163)
Browse files Browse the repository at this point in the history
Co-authored-by: Kevin Pike <kevipike@amazon.com>
  • Loading branch information
KevinPike and Kevin Pike authored Oct 15, 2020
1 parent 5ed622d commit 65f6a63
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 21 deletions.
7 changes: 5 additions & 2 deletions cfn/handler/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ type ProgressEvent struct {
// and by CREATE/UPDATE/DELETE for final response validation/confirmation
ResourceModel interface{} `json:"resourceModel,omitempty"`

// ResourceModels is the output resource instances populated by a LIST for synchronous results
ResourceModels []interface{} `json:"resourceModels,omitempty"`
// ResourceModels is the output resource instances populated by a LIST for
// synchronous results. ResourceModels must be returned by LIST so it's
// always included in the response. When ResourceModels is not set, null is
// returned.
ResourceModels []interface{} `json:"resourceModels"`

// NextToken is the token used to request additional pages of resources for a LIST operation
NextToken string `json:"nextToken,omitempty"`
Expand Down
73 changes: 73 additions & 0 deletions cfn/handler/event_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package handler

import (
"testing"

"github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/google/go-cmp/cmp"

"encoding/json"

"github.com/aws-cloudformation/cloudformation-cli-go-plugin/cfn/encoding"
)

func TestProgressEventMarshalJSON(t *testing.T) {
type Model struct {
Name *encoding.String
Version *encoding.Float
}

for _, tt := range []struct {
name string
event ProgressEvent
expected string
}{
{
name: "not updatable",
event: ProgressEvent{
Message: "foo",
OperationStatus: Failed,
ResourceModel: Model{
Name: encoding.NewString("Douglas"),
Version: encoding.NewFloat(42.1),
},
HandlerErrorCode: cloudformation.HandlerErrorCodeNotUpdatable,
},
expected: `{"status":"FAILED","errorCode":"NotUpdatable","message":"foo","resourceModel":{"Name":"Douglas","Version":"42.1"},"resourceModels":null}`,
},
{
name: "list with 1 result",
event: ProgressEvent{
OperationStatus: Success,
ResourceModels: []interface{}{
Model{
Name: encoding.NewString("Douglas"),
Version: encoding.NewFloat(42.1),
},
},
},
expected: `{"status":"SUCCESS","resourceModels":[{"Name":"Douglas","Version":"42.1"}]}`,
},
{
name: "list with empty array",
event: ProgressEvent{
OperationStatus: Success,
ResourceModels: []interface{}{},
},
expected: `{"status":"SUCCESS","resourceModels":[]}`,
},
} {
t.Run(tt.name, func(t *testing.T) {

actual, err := json.Marshal(tt.event)
if err != nil {
t.Errorf("Unexpected error marshaling event JSON: %s", err)
}

if diff := cmp.Diff(string(actual), tt.expected); diff != "" {
t.Errorf(diff)
}
})
}

}
7 changes: 5 additions & 2 deletions cfn/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ type response struct {
//passed back to CloudFormation
BearerToken string `json:"bearerToken,omitempty"`

// ResourceModels is the output resource instances populated by a LIST for synchronous results
ResourceModels []interface{} `json:"resourceModels,omitempty"`
// ResourceModels is the output resource instances populated by a LIST for
// synchronous results. ResourceModels must be returned by LIST so it's
// always included in the response. When ResourceModels is not set, null is
// returned.
ResourceModels []interface{} `json:"resourceModels"`

// NextToken the token used to request additional pages of resources for a LIST operation
NextToken string `json:"nextToken,omitempty"`
Expand Down
69 changes: 52 additions & 17 deletions cfn/response_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,66 @@ import (
"github.com/aws-cloudformation/cloudformation-cli-go-plugin/cfn/handler"
)

func TestMarshalJSON(t *testing.T) {
func TestResponseMarshalJSON(t *testing.T) {
type Model struct {
Name *encoding.String
Version *encoding.Float
}

r := response{
Message: "foo",
OperationStatus: handler.Success,
ResourceModel: Model{
Name: encoding.NewString("Douglas"),
Version: encoding.NewFloat(42.1),
for _, tt := range []struct {
name string
response response
expected string
}{
{
name: "updated failed",
response: response{
Message: "foo",
OperationStatus: handler.Failed,
ResourceModel: Model{
Name: encoding.NewString("Douglas"),
Version: encoding.NewFloat(42.1),
},
ErrorCode: cloudformation.HandlerErrorCodeNotUpdatable,
BearerToken: "xyzzy",
},
expected: `{"message":"foo","status":"FAILED","resourceModel":{"Name":"Douglas","Version":"42.1"},"errorCode":"NotUpdatable","bearerToken":"xyzzy","resourceModels":null}`,
},
ErrorCode: cloudformation.HandlerErrorCodeNotUpdatable,
BearerToken: "xyzzy",
}
{
name: "list with 1 result",
response: response{
OperationStatus: handler.Success,
ResourceModels: []interface{}{
Model{
Name: encoding.NewString("Douglas"),
Version: encoding.NewFloat(42.1),
},
},
BearerToken: "xyzzy",
},
expected: `{"status":"SUCCESS","bearerToken":"xyzzy","resourceModels":[{"Name":"Douglas","Version":"42.1"}]}`,
},
{
name: "list with empty array",
response: response{
OperationStatus: handler.Success,
ResourceModels: []interface{}{},
BearerToken: "xyzzy",
},
expected: `{"status":"SUCCESS","bearerToken":"xyzzy","resourceModels":[]}`,
},
} {
t.Run(tt.name, func(t *testing.T) {

expected := `{"message":"foo","status":"SUCCESS","resourceModel":{"Name":"Douglas","Version":"42.1"},"errorCode":"NotUpdatable","bearerToken":"xyzzy"}`
actual, err := json.Marshal(tt.response)
if err != nil {
t.Errorf("Unexpected error marshaling response JSON: %s", err)
}

actual, err := json.Marshal(r)
if err != nil {
t.Errorf("Unexpected error marshaling response JSON: %s", err)
if diff := cmp.Diff(string(actual), tt.expected); diff != "" {
t.Errorf(diff)
}
})
}

if diff := cmp.Diff(string(actual), expected); diff != "" {
t.Errorf(diff)
}
}

0 comments on commit 65f6a63

Please sign in to comment.