Skip to content

Commit 2ebd752

Browse files
authored
Add operation poller unit tests (#40)
1 parent b628cd9 commit 2ebd752

File tree

4 files changed

+273
-27
lines changed

4 files changed

+273
-27
lines changed

pkg/cloudmap/api.go

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cloudmap
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"github.com/aws/aws-cloud-map-mcs-controller-for-k8s/pkg/model"
78
"github.com/aws/aws-sdk-go-v2/aws"
@@ -16,10 +17,10 @@ import (
1617
// internal data structures. It manages all interactions with the AWS SDK.
1718
type ServiceDiscoveryApi interface {
1819
// ListNamespaces returns a list of all namespaces.
19-
ListNamespaces(ctx context.Context) (namespaces []*Resource, err error)
20+
ListNamespaces(ctx context.Context) (namespaces []*model.Resource, err error)
2021

2122
// ListServices returns a list of services for a given namespace.
22-
ListServices(ctx context.Context, namespaceId string) (services []*Resource, err error)
23+
ListServices(ctx context.Context, namespaceId string) (services []*model.Resource, err error)
2324

2425
// ListInstances returns a list of service instances registered to a given service.
2526
ListInstances(ctx context.Context, serviceId string) ([]*model.Endpoint, error)
@@ -51,12 +52,6 @@ type serviceDiscoveryApi struct {
5152
awsFacade AwsFacade
5253
}
5354

54-
// Resource encapsulates a ID/name pair
55-
type Resource struct {
56-
Id string
57-
Name string
58-
}
59-
6055
// NewServiceDiscoveryApiFromConfig creates a new AWS Cloud Map API connection manager from an AWS client config.
6156
func NewServiceDiscoveryApiFromConfig(cfg *aws.Config) ServiceDiscoveryApi {
6257
return &serviceDiscoveryApi{
@@ -65,8 +60,8 @@ func NewServiceDiscoveryApiFromConfig(cfg *aws.Config) ServiceDiscoveryApi {
6560
}
6661
}
6762

68-
func (sdApi *serviceDiscoveryApi) ListNamespaces(ctx context.Context) ([]*Resource, error) {
69-
namespaces := make([]*Resource, 0)
63+
func (sdApi *serviceDiscoveryApi) ListNamespaces(ctx context.Context) ([]*model.Resource, error) {
64+
namespaces := make([]*model.Resource, 0)
7065
pages := sd.NewListNamespacesPaginator(sdApi.awsFacade, &sd.ListNamespacesInput{})
7166

7267
for pages.HasMorePages() {
@@ -76,7 +71,7 @@ func (sdApi *serviceDiscoveryApi) ListNamespaces(ctx context.Context) ([]*Resour
7671
}
7772

7873
for _, ns := range output.Namespaces {
79-
namespaces = append(namespaces, &Resource{
74+
namespaces = append(namespaces, &model.Resource{
8075
Id: aws.ToString(ns.Id),
8176
Name: aws.ToString(ns.Name),
8277
})
@@ -86,8 +81,8 @@ func (sdApi *serviceDiscoveryApi) ListNamespaces(ctx context.Context) ([]*Resour
8681
return namespaces, nil
8782
}
8883

89-
func (sdApi *serviceDiscoveryApi) ListServices(ctx context.Context, nsId string) ([]*Resource, error) {
90-
svcs := make([]*Resource, 0)
84+
func (sdApi *serviceDiscoveryApi) ListServices(ctx context.Context, nsId string) ([]*model.Resource, error) {
85+
svcs := make([]*model.Resource, 0)
9186

9287
filter := types.ServiceFilter{
9388
Name: types.ServiceFilterNameNamespaceId,
@@ -103,7 +98,7 @@ func (sdApi *serviceDiscoveryApi) ListServices(ctx context.Context, nsId string)
10398
}
10499

105100
for _, svc := range output.Services {
106-
svcs = append(svcs, &Resource{
101+
svcs = append(svcs, &model.Resource{
107102
Id: aws.ToString(svc.Id),
108103
Name: aws.ToString(svc.Name),
109104
})
@@ -226,12 +221,12 @@ func (sdApi *serviceDiscoveryApi) DeregisterInstance(ctx context.Context, svcId
226221
}
227222

228223
func (sdApi *serviceDiscoveryApi) PollCreateNamespace(ctx context.Context, opId string) (nsId string, err error) {
229-
return nsId, wait.Poll(defaultOperationPollInterval, defaultOperationPollTimeout, func() (done bool, pollErr error) {
224+
err = wait.Poll(defaultOperationPollInterval, defaultOperationPollTimeout, func() (done bool, err error) {
230225
sdApi.log.Info("polling operation", "opId", opId)
231-
op, opErr := sdApi.GetOperation(ctx, opId)
226+
op, err := sdApi.GetOperation(ctx, opId)
232227

233-
if opErr != nil {
234-
return true, opErr
228+
if err != nil {
229+
return true, err
235230
}
236231

237232
if op.Status == types.OperationStatusFail {
@@ -246,4 +241,10 @@ func (sdApi *serviceDiscoveryApi) PollCreateNamespace(ctx context.Context, opId
246241

247242
return false, nil
248243
})
244+
245+
if err == wait.ErrWaitTimeout {
246+
err = errors.New(operationPollTimoutErrorMessage)
247+
}
248+
249+
return nsId, err
249250
}

pkg/cloudmap/operation_poller.go

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package cloudmap
22

33
import (
44
"context"
5-
"fmt"
5+
"errors"
66
"github.com/aws/aws-sdk-go-v2/aws"
77
"github.com/aws/aws-sdk-go-v2/service/servicediscovery/types"
88
"github.com/go-logr/logr"
@@ -18,6 +18,8 @@ const (
1818

1919
// Time until we stop polling the operation
2020
defaultOperationPollTimeout = 5 * time.Minute
21+
22+
operationPollTimoutErrorMessage = "timed out while polling operations"
2123
)
2224

2325
// OperationPoller polls a list operations for a terminal status.
@@ -27,19 +29,21 @@ type OperationPoller interface {
2729
}
2830

2931
type operationPoller struct {
30-
log logr.Logger
31-
sdApi ServiceDiscoveryApi
32-
opIds []string
32+
log logr.Logger
33+
sdApi ServiceDiscoveryApi
34+
timeout time.Duration
3335

36+
opIds []string
3437
svcId string
3538
opType types.OperationType
3639
start int64
3740
}
3841

3942
func newOperationPoller(sdApi ServiceDiscoveryApi, svcId string, opIds []string, startTime int64) operationPoller {
4043
return operationPoller{
41-
log: ctrl.Log.WithName("cloudmap"),
42-
sdApi: sdApi,
44+
log: ctrl.Log.WithName("cloudmap"),
45+
sdApi: sdApi,
46+
timeout: defaultOperationPollTimeout,
4347

4448
opIds: opIds,
4549
svcId: svcId,
@@ -67,7 +71,7 @@ func (opPoller *operationPoller) Poll(ctx context.Context) (err error) {
6771
return nil
6872
}
6973

70-
return wait.Poll(defaultOperationPollInterval, defaultOperationPollTimeout, func() (done bool, err error) {
74+
err = wait.Poll(defaultOperationPollInterval, opPoller.timeout, func() (done bool, err error) {
7175
opPoller.log.Info("polling operations", "operations", opPoller.opIds)
7276

7377
sdOps, err := opPoller.sdApi.ListOperations(ctx, opPoller.buildFilters())
@@ -92,14 +96,20 @@ func (opPoller *operationPoller) Poll(ctx context.Context) (err error) {
9296

9397
if len(failedOps) != 0 {
9498
for _, failedOp := range failedOps {
95-
opPoller.log.Info("Operation failed", "failedOp", failedOp, "reason", opPoller.getFailedOpReason(ctx, failedOp))
99+
opPoller.log.Info("operation failed", "failedOp", failedOp, "reason", opPoller.getFailedOpReason(ctx, failedOp))
96100
}
97-
return true, fmt.Errorf("operation failure")
101+
return true, errors.New("operation failure")
98102
}
99103

100104
opPoller.log.Info("operations completed successfully")
101105
return true, nil
102106
})
107+
108+
if err == wait.ErrWaitTimeout {
109+
return errors.New(operationPollTimoutErrorMessage)
110+
}
111+
112+
return err
103113
}
104114

105115
func (opPoller *operationPoller) buildFilters() []types.OperationFilter {

0 commit comments

Comments
 (0)