Skip to content

Commit

Permalink
Modify tags related functions and some test files to fix flaky assert…
Browse files Browse the repository at this point in the history
…ion errors (aws-controllers-k8s#51)

Issue #, if available:
MemoryDB Controller has some flaky tests that randomly show assertion error.
Root causes:
1. Snapshot test files didn't clean resources which were created from previous failed tests, so eventually test account reached node limit.
2. Delta compare considers order matters, so it considers two tag arrays are different even though they have same elements with different orders. Function of updating tags didn't include this corner case, and it caused infinite update.
3. When creating resources, some resources take a while to finish creation. Function of getting tags got error because it couldn't find resource, and this error covered previous ResourceNotFound error. Hence, reconciler didn't call requeue, because it didn't recognize the new error.
4. Cluster update validation test file has a step to update and validate Snapshot Window (daily time range to auto snapshot). If this step is executing within the time range of new Snapshot Window, update would succeed (ResourceSynced returns true) because two resources match, but cluster starts snapshotting after it's Snapshot Window is updated to the current time. Hence, for next step to update other fields of cluster, new fields couldn't be updated on time, because the status of cluster is snapshotting and cluster cannot be updated.

Description of changes:
1. Fix updateTags function and it covers situation of equal tag arrays. (It still wastes time to call sdkUpdate over and over. It is better to modify delta comparison of tags in code-generator. New PR is created (aws-controllers-k8s/community#1658).
2. Change updateTags functions from parameter group and subnet group to match the updateTags functions in other resources.
3. Add a status check for getTags. It is only called when status of resource (cluster, snapshot, acl, user) is active.
4. Increase wait time for the next update step after Snapshot Window update. The new wait time is enough to cover snapshotting process.
5. Use same method to create cluster for snapshot for snapshot_validate_tags.yaml test file.
6. Correct user names and delete unused resources in test files.
7. Modify some test IDs, step IDs, and descriptions which are not appropriate that makes debugging really hard.
8. Fix import order of hook files.
9. Modify equalStrings function.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
  • Loading branch information
kyriechen96 authored and Kyrie Chen committed Feb 6, 2023
1 parent d2483d2 commit 482ffad
Show file tree
Hide file tree
Showing 35 changed files with 327 additions and 194 deletions.
12 changes: 6 additions & 6 deletions apis/v1alpha1/ack-generate-metadata.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
ack_generate_info:
build_date: "2023-01-10T21:58:28Z"
build_hash: 1b20baf45a0b73a11b296050322a384c705fa897
go_version: go1.17.5
version: v0.22.0
api_directory_checksum: ee32acc4d4a0ba7e2823dd20fdbe2c4ef1d9e0f4
build_date: "2023-02-06T23:57:24Z"
build_hash: 9c9c7c2e841a27e56ea46dc962bf026ea6857912
go_version: go1.19
version: v0.23.1-2-g9c9c7c2
api_directory_checksum: 585f390bd5f6e7f305c0202cc5982c5b63a14947
api_version: v1alpha1
aws_sdk_go_version: v1.44.93
generator_config_info:
file_checksum: d7ad13c5bc8d9e9e2171c92dc3ac51c2b5e3b769
file_checksum: 48977f3ee0ba02781e608ede837865bbe0ef4ce4
original_file_name: generator.yaml
last_modification:
reason: API generation
5 changes: 5 additions & 0 deletions apis/v1alpha1/generator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,11 @@ resources:
DescribeSnapshots:
input_fields:
SnapshotName: Name
synced:
when:
- path: Status.Status
in:
- available
ParameterGroup:
exceptions:
errors:
Expand Down
3 changes: 2 additions & 1 deletion apis/v1alpha1/snapshot.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions apis/v1alpha1/subnet_group.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions apis/v1alpha1/types.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions config/controller/deployment.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
apiVersion: v1
kind: Namespace
metadata:
labels:
control-plane: controller
name: ack-system
---
apiVersion: apps/v1
Expand All @@ -11,16 +9,17 @@ metadata:
name: ack-memorydb-controller
namespace: ack-system
labels:
control-plane: controller
app.kubernetes.io/name: ack-memorydb-controller
app.kubernetes.io/part-of: ack-system
spec:
selector:
matchLabels:
control-plane: controller
app.kubernetes.io/name: ack-memorydb-controller
replicas: 1
template:
metadata:
labels:
control-plane: controller
app.kubernetes.io/name: ack-memorydb-controller
spec:
containers:
- command:
Expand Down
2 changes: 1 addition & 1 deletion config/controller/service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ metadata:
namespace: ack-system
spec:
selector:
control-plane: controller
app.kubernetes.io/name: ack-memorydb-controller
ports:
- name: metricsport
port: 8080
Expand Down
1 change: 1 addition & 0 deletions config/crd/bases/memorydb.services.k8s.aws_snapshots.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ spec:
type: object
type: array
required:
- clusterName
- name
type: object
status:
Expand Down
5 changes: 5 additions & 0 deletions generator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,11 @@ resources:
DescribeSnapshots:
input_fields:
SnapshotName: Name
synced:
when:
- path: Status.Status
in:
- available
ParameterGroup:
exceptions:
errors:
Expand Down
1 change: 1 addition & 0 deletions helm/crds/memorydb.services.k8s.aws_snapshots.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ spec:
type: object
type: array
required:
- clusterName
- name
type: object
status:
Expand Down
4 changes: 2 additions & 2 deletions helm/crds/memorydb.services.k8s.aws_subnetgroups.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ spec:
type: object
spec:
description: "SubnetGroupSpec defines the desired state of SubnetGroup.
\n Represents the output of one of the following operations: \n * CreateSubnetGroup
\n * UpdateSubnetGroup \n A subnet group is a collection of subnets
\n Represents the output of one of the following operations: \n - CreateSubnetGroup
\n - UpdateSubnetGroup \n A subnet group is a collection of subnets
(typically private) that you can designate for your clusters running
in an Amazon Virtual Private Cloud (VPC) environment."
properties:
Expand Down
1 change: 0 additions & 1 deletion helm/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ metadata:
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
k8s-app: {{ include "app.name" . }}
helm.sh/chart: {{ include "chart.name-version" . }}
control-plane: controller
spec:
replicas: 1
selector:
Expand Down
1 change: 0 additions & 1 deletion helm/templates/metrics-service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ metadata:
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
k8s-app: {{ include "app.name" . }}
helm.sh/chart: {{ include "chart.name-version" . }}
control-plane: controller
spec:
selector:
app.kubernetes.io/name: {{ include "app.name" . }}
Expand Down
30 changes: 25 additions & 5 deletions pkg/resource/acl/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@ import (
"github.com/aws-controllers-k8s/runtime/pkg/requeue"
ackrtlog "github.com/aws-controllers-k8s/runtime/pkg/runtime/log"
ackutil "github.com/aws-controllers-k8s/runtime/pkg/util"
svcsdk "github.com/aws/aws-sdk-go/service/memorydb"

svcapitypes "github.com/aws-controllers-k8s/memorydb-controller/apis/v1alpha1"
svcsdk "github.com/aws/aws-sdk-go/service/memorydb"
)

var (
resourceStatusActive string = "active"
)

// validateACLNeedsUpdate this function's purpose is to requeue if the resource is currently unavailable
Expand All @@ -32,7 +36,7 @@ func (rm *resourceManager) validateACLNeedsUpdate(

// requeue if necessary
latestStatus := latest.ko.Status.Status
if latestStatus == nil || *latestStatus != "active" {
if latestStatus == nil || *latestStatus != resourceStatusActive {
return requeue.NeededAfter(
errors.New("ACL cannot be modified as its status is not 'active'."),
requeue.DefaultRequeueAfterDuration)
Expand All @@ -41,6 +45,14 @@ func (rm *resourceManager) validateACLNeedsUpdate(
return nil
}

// isAclActive returns true when the status of the given ACL is set to `active`
func (rm *resourceManager) isAclActive(
latest *resource,
) bool {
latestStatus := latest.ko.Status.Status
return latestStatus != nil && *latestStatus == resourceStatusActive
}

// getTags gets tags from given ParameterGroup.
func (rm *resourceManager) getTags(
ctx context.Context,
Expand Down Expand Up @@ -114,17 +126,23 @@ func computeTagsDelta(
latest []*svcapitypes.Tag,
) (addedOrUpdated []*svcapitypes.Tag, removed []*string) {
var visitedIndexes []string
var hasSameKey bool

for _, latestElement := range latest {
hasSameKey = false
visitedIndexes = append(visitedIndexes, *latestElement.Key)
for _, desiredElement := range desired {
if equalStrings(latestElement.Key, desiredElement.Key) {
hasSameKey = true
if !equalStrings(latestElement.Value, desiredElement.Value) {
addedOrUpdated = append(addedOrUpdated, desiredElement)
}
continue
break
}
}
if hasSameKey {
continue
}
removed = append(removed, latestElement.Key)
}
for _, desiredElement := range desired {
Expand Down Expand Up @@ -163,7 +181,9 @@ func resourceTagsFromSDKTags(

func equalStrings(a, b *string) bool {
if a == nil {
return b == nil || *b == ""
return b == nil
} else if b == nil {
return false
}
return (*a == "" && b == nil) || *a == *b
return *a == *b
}
12 changes: 7 additions & 5 deletions pkg/resource/acl/sdk.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 23 additions & 6 deletions pkg/resource/cluster/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ import (
ackrequeue "github.com/aws-controllers-k8s/runtime/pkg/requeue"
ackrtlog "github.com/aws-controllers-k8s/runtime/pkg/runtime/log"
ackutil "github.com/aws-controllers-k8s/runtime/pkg/util"
svcsdk "github.com/aws/aws-sdk-go/service/memorydb"

svcapitypes "github.com/aws-controllers-k8s/memorydb-controller/apis/v1alpha1"
svcsdk "github.com/aws/aws-sdk-go/service/memorydb"
)

var (
condMsgCurrentlyDeleting = "cluster currently being deleted"
condMsgNoDeleteWhileUpdating = "cluster is being updated. cannot delete"
condMsgCurrentlyDeleting = "cluster currently being deleted"
condMsgNoDeleteWhileUpdating = "cluster is being updated. cannot delete"
resourceStatusActive string = "active"
)

var (
Expand Down Expand Up @@ -264,6 +265,14 @@ func (rm *resourceManager) newMemoryDBClusterUploadPayload(
return res
}

// isClusterActive returns true when the status of the given Cluster is set to `active`
func (rm *resourceManager) isClusterActive(
latest *resource,
) bool {
latestStatus := latest.ko.Status.Status
return latestStatus != nil && *latestStatus == resourceStatusActive
}

// getTags gets tags from given ParameterGroup.
func (rm *resourceManager) getTags(
ctx context.Context,
Expand Down Expand Up @@ -337,17 +346,23 @@ func computeTagsDelta(
latest []*svcapitypes.Tag,
) (addedOrUpdated []*svcapitypes.Tag, removed []*string) {
var visitedIndexes []string
var hasSameKey bool

for _, latestElement := range latest {
hasSameKey = false
visitedIndexes = append(visitedIndexes, *latestElement.Key)
for _, desiredElement := range desired {
if equalStrings(latestElement.Key, desiredElement.Key) {
hasSameKey = true
if !equalStrings(latestElement.Value, desiredElement.Value) {
addedOrUpdated = append(addedOrUpdated, desiredElement)
}
continue
break
}
}
if hasSameKey {
continue
}
removed = append(removed, latestElement.Key)
}
for _, desiredElement := range desired {
Expand Down Expand Up @@ -386,7 +401,9 @@ func resourceTagsFromSDKTags(

func equalStrings(a, b *string) bool {
if a == nil {
return b == nil || *b == ""
return b == nil
} else if b == nil {
return false
}
return (*a == "" && b == nil) || *a == *b
return *a == *b
}
12 changes: 7 additions & 5 deletions pkg/resource/cluster/sdk.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 482ffad

Please sign in to comment.