Skip to content

Commit 65f6a63

Browse files
KevinPikeKevin Pike
andauthored
LIST returns empty array (#163)
Co-authored-by: Kevin Pike <[email protected]>
1 parent 5ed622d commit 65f6a63

File tree

4 files changed

+135
-21
lines changed

4 files changed

+135
-21
lines changed

cfn/handler/event.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@ type ProgressEvent struct {
3434
// and by CREATE/UPDATE/DELETE for final response validation/confirmation
3535
ResourceModel interface{} `json:"resourceModel,omitempty"`
3636

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

4043
// NextToken is the token used to request additional pages of resources for a LIST operation
4144
NextToken string `json:"nextToken,omitempty"`

cfn/handler/event_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package handler
2+
3+
import (
4+
"testing"
5+
6+
"github.com/aws/aws-sdk-go/service/cloudformation"
7+
"github.com/google/go-cmp/cmp"
8+
9+
"encoding/json"
10+
11+
"github.com/aws-cloudformation/cloudformation-cli-go-plugin/cfn/encoding"
12+
)
13+
14+
func TestProgressEventMarshalJSON(t *testing.T) {
15+
type Model struct {
16+
Name *encoding.String
17+
Version *encoding.Float
18+
}
19+
20+
for _, tt := range []struct {
21+
name string
22+
event ProgressEvent
23+
expected string
24+
}{
25+
{
26+
name: "not updatable",
27+
event: ProgressEvent{
28+
Message: "foo",
29+
OperationStatus: Failed,
30+
ResourceModel: Model{
31+
Name: encoding.NewString("Douglas"),
32+
Version: encoding.NewFloat(42.1),
33+
},
34+
HandlerErrorCode: cloudformation.HandlerErrorCodeNotUpdatable,
35+
},
36+
expected: `{"status":"FAILED","errorCode":"NotUpdatable","message":"foo","resourceModel":{"Name":"Douglas","Version":"42.1"},"resourceModels":null}`,
37+
},
38+
{
39+
name: "list with 1 result",
40+
event: ProgressEvent{
41+
OperationStatus: Success,
42+
ResourceModels: []interface{}{
43+
Model{
44+
Name: encoding.NewString("Douglas"),
45+
Version: encoding.NewFloat(42.1),
46+
},
47+
},
48+
},
49+
expected: `{"status":"SUCCESS","resourceModels":[{"Name":"Douglas","Version":"42.1"}]}`,
50+
},
51+
{
52+
name: "list with empty array",
53+
event: ProgressEvent{
54+
OperationStatus: Success,
55+
ResourceModels: []interface{}{},
56+
},
57+
expected: `{"status":"SUCCESS","resourceModels":[]}`,
58+
},
59+
} {
60+
t.Run(tt.name, func(t *testing.T) {
61+
62+
actual, err := json.Marshal(tt.event)
63+
if err != nil {
64+
t.Errorf("Unexpected error marshaling event JSON: %s", err)
65+
}
66+
67+
if diff := cmp.Diff(string(actual), tt.expected); diff != "" {
68+
t.Errorf(diff)
69+
}
70+
})
71+
}
72+
73+
}

cfn/response.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@ type response struct {
3131
//passed back to CloudFormation
3232
BearerToken string `json:"bearerToken,omitempty"`
3333

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

3740
// NextToken the token used to request additional pages of resources for a LIST operation
3841
NextToken string `json:"nextToken,omitempty"`

cfn/response_test.go

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,66 @@ import (
1212
"github.com/aws-cloudformation/cloudformation-cli-go-plugin/cfn/handler"
1313
)
1414

15-
func TestMarshalJSON(t *testing.T) {
15+
func TestResponseMarshalJSON(t *testing.T) {
1616
type Model struct {
1717
Name *encoding.String
1818
Version *encoding.Float
1919
}
2020

21-
r := response{
22-
Message: "foo",
23-
OperationStatus: handler.Success,
24-
ResourceModel: Model{
25-
Name: encoding.NewString("Douglas"),
26-
Version: encoding.NewFloat(42.1),
21+
for _, tt := range []struct {
22+
name string
23+
response response
24+
expected string
25+
}{
26+
{
27+
name: "updated failed",
28+
response: response{
29+
Message: "foo",
30+
OperationStatus: handler.Failed,
31+
ResourceModel: Model{
32+
Name: encoding.NewString("Douglas"),
33+
Version: encoding.NewFloat(42.1),
34+
},
35+
ErrorCode: cloudformation.HandlerErrorCodeNotUpdatable,
36+
BearerToken: "xyzzy",
37+
},
38+
expected: `{"message":"foo","status":"FAILED","resourceModel":{"Name":"Douglas","Version":"42.1"},"errorCode":"NotUpdatable","bearerToken":"xyzzy","resourceModels":null}`,
2739
},
28-
ErrorCode: cloudformation.HandlerErrorCodeNotUpdatable,
29-
BearerToken: "xyzzy",
30-
}
40+
{
41+
name: "list with 1 result",
42+
response: response{
43+
OperationStatus: handler.Success,
44+
ResourceModels: []interface{}{
45+
Model{
46+
Name: encoding.NewString("Douglas"),
47+
Version: encoding.NewFloat(42.1),
48+
},
49+
},
50+
BearerToken: "xyzzy",
51+
},
52+
expected: `{"status":"SUCCESS","bearerToken":"xyzzy","resourceModels":[{"Name":"Douglas","Version":"42.1"}]}`,
53+
},
54+
{
55+
name: "list with empty array",
56+
response: response{
57+
OperationStatus: handler.Success,
58+
ResourceModels: []interface{}{},
59+
BearerToken: "xyzzy",
60+
},
61+
expected: `{"status":"SUCCESS","bearerToken":"xyzzy","resourceModels":[]}`,
62+
},
63+
} {
64+
t.Run(tt.name, func(t *testing.T) {
3165

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

34-
actual, err := json.Marshal(r)
35-
if err != nil {
36-
t.Errorf("Unexpected error marshaling response JSON: %s", err)
71+
if diff := cmp.Diff(string(actual), tt.expected); diff != "" {
72+
t.Errorf(diff)
73+
}
74+
})
3775
}
3876

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

0 commit comments

Comments
 (0)