-
-
Notifications
You must be signed in to change notification settings - Fork 359
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
74ab0b4
commit 0f69d82
Showing
4 changed files
with
111 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,128 +1,117 @@ | ||
package aws | ||
|
||
import ( | ||
"github.com/gruntwork-io/cloud-nuke/telemetry" | ||
"testing" | ||
"time" | ||
|
||
"github.com/gruntwork-io/cloud-nuke/logging" | ||
"github.com/gruntwork-io/go-commons/retry" | ||
|
||
"github.com/aws/aws-sdk-go-v2/aws" | ||
awsgo "github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/session" | ||
"github.com/aws/aws-sdk-go/service/sqs" | ||
"github.com/gruntwork-io/cloud-nuke/util" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/aws/aws-sdk-go/service/sqs/sqsiface" | ||
"github.com/gruntwork-io/cloud-nuke/config" | ||
"github.com/gruntwork-io/cloud-nuke/telemetry" | ||
"github.com/stretchr/testify/require" | ||
"regexp" | ||
"testing" | ||
"time" | ||
) | ||
|
||
func createTestQueue(t *testing.T, session *session.Session, name string) *string { | ||
svc := sqs.New(session) | ||
type mockedSqsQueue struct { | ||
sqsiface.SQSAPI | ||
DeleteQueueOutput sqs.DeleteQueueOutput | ||
GetQueueAttributesOutput map[string]sqs.GetQueueAttributesOutput | ||
ListQueuesOutput sqs.ListQueuesOutput | ||
} | ||
|
||
param := &sqs.CreateQueueInput{ | ||
QueueName: awsgo.String(name), | ||
Attributes: map[string]*string{ | ||
"DelaySeconds": awsgo.String("60"), | ||
"MessageRetentionPeriod": awsgo.String("86400"), | ||
}, | ||
} | ||
func (m mockedSqsQueue) ListQueuesPages(input *sqs.ListQueuesInput, fn func(*sqs.ListQueuesOutput, bool) bool) error { | ||
fn(&m.ListQueuesOutput, true) | ||
return nil | ||
} | ||
|
||
result, err := svc.CreateQueue(param) | ||
require.NoError(t, err) | ||
require.True(t, len(awsgo.StringValue(result.QueueUrl)) > 0, "Can't create test Sqs Queue") | ||
func (m mockedSqsQueue) GetQueueAttributes(input *sqs.GetQueueAttributesInput) (*sqs.GetQueueAttributesOutput, error) { | ||
url := input.QueueUrl | ||
resp := m.GetQueueAttributesOutput[*url] | ||
|
||
err = retry.DoWithRetry( | ||
logging.Logger, | ||
"Check if queue is created", | ||
3, | ||
5*time.Second, | ||
func() error { | ||
_, err = svc.GetQueueUrl(&sqs.GetQueueUrlInput{QueueName: awsgo.String(name)}) | ||
return err | ||
}, | ||
) | ||
require.NoError(t, err) | ||
return result.QueueUrl | ||
return &resp, nil | ||
} | ||
|
||
func TestListSqsQueue(t *testing.T) { | ||
func (m mockedSqsQueue) DeleteQueue(*sqs.DeleteQueueInput) (*sqs.DeleteQueueOutput, error) { | ||
return &m.DeleteQueueOutput, nil | ||
} | ||
|
||
func TestSqsQueue_GetAll(t *testing.T) { | ||
telemetry.InitTelemetry("cloud-nuke", "") | ||
t.Parallel() | ||
|
||
region, err := getRandomRegion() | ||
require.NoError(t, err) | ||
|
||
session, err := session.NewSession(&awsgo.Config{ | ||
Region: awsgo.String(region)}, | ||
) | ||
require.NoError(t, err) | ||
|
||
// create 20 test queues, to validate pagination | ||
queueList := []*string{} | ||
for n := 0; n < 20; n++ { | ||
queueName := "cloud-nuke-test-" + util.UniqueID() | ||
queueUrl := createTestQueue(t, session, queueName) | ||
require.NoError(t, err) | ||
|
||
queueList = append(queueList, queueUrl) | ||
queue1 := "https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue1" | ||
queue2 := "https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue2" | ||
now := time.Now() | ||
sq := SqsQueue{ | ||
Client: mockedSqsQueue{ | ||
ListQueuesOutput: sqs.ListQueuesOutput{ | ||
QueueUrls: []*string{ | ||
awsgo.String(queue1), | ||
awsgo.String(queue2), | ||
}, | ||
}, | ||
GetQueueAttributesOutput: map[string]sqs.GetQueueAttributesOutput{ | ||
queue1: { | ||
Attributes: map[string]*string{ | ||
"CreatedTimestamp": awsgo.String(now.Format(time.RFC3339)), | ||
}, | ||
}, | ||
queue2: { | ||
Attributes: map[string]*string{ | ||
"CreatedTimestamp": awsgo.String(now.Add(1).Format(time.RFC3339)), | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
// clean up after this test | ||
defer nukeAllSqsQueues(session, queueList) | ||
|
||
// timestamps to test | ||
oneHourAgo := time.Now().Add(1 * time.Hour * -1) | ||
oneHourFromNow := time.Now().Add(1 * time.Hour) | ||
|
||
urls, err := getAllSqsQueue(session, region, oneHourAgo) | ||
require.NoError(t, err) | ||
|
||
for _, queue := range queueList { | ||
assert.NotContains(t, awsgo.StringValueSlice(urls), awsgo.StringValue(queue)) | ||
tests := map[string]struct { | ||
configObj config.ResourceType | ||
expected []string | ||
}{ | ||
"emptyFilter": { | ||
configObj: config.ResourceType{}, | ||
expected: []string{queue1, queue2}, | ||
}, | ||
"nameExclusionFilter": { | ||
configObj: config.ResourceType{ | ||
ExcludeRule: config.FilterRule{ | ||
NamesRegExp: []config.Expression{{ | ||
RE: *regexp.MustCompile("MyQueue1"), | ||
}}}, | ||
}, | ||
expected: []string{queue2}, | ||
}, | ||
"timeAfterExclusionFilter": { | ||
configObj: config.ResourceType{ | ||
ExcludeRule: config.FilterRule{ | ||
TimeAfter: aws.Time(now.Add(-1 * time.Hour)), | ||
}}, | ||
expected: []string{}, | ||
}, | ||
} | ||
|
||
urls, err = getAllSqsQueue(session, region, oneHourFromNow) | ||
require.NoError(t, err) | ||
|
||
for _, queue := range queueList { | ||
assert.Contains(t, awsgo.StringValueSlice(urls), awsgo.StringValue(queue)) | ||
for name, tc := range tests { | ||
t.Run(name, func(t *testing.T) { | ||
names, err := sq.getAll(config.Config{ | ||
SQS: tc.configObj, | ||
}) | ||
require.NoError(t, err) | ||
require.Equal(t, tc.expected, awsgo.StringValueSlice(names)) | ||
}) | ||
} | ||
} | ||
|
||
func TestNukeSqsQueue(t *testing.T) { | ||
func TestSqsQueue_NukeAll(t *testing.T) { | ||
telemetry.InitTelemetry("cloud-nuke", "") | ||
t.Parallel() | ||
|
||
region, err := getRandomRegion() | ||
require.NoError(t, err) | ||
|
||
session, err := session.NewSession(&awsgo.Config{ | ||
Region: awsgo.String(region)}, | ||
) | ||
require.NoError(t, err) | ||
|
||
queueName := "cloud-nuke-test-" + util.UniqueID() | ||
queueUrl := createTestQueue(t, session, queueName) | ||
oneHourFromNow := time.Now().Add(1 * time.Hour) | ||
|
||
urls, err := getAllSqsQueue(session, region, oneHourFromNow) | ||
require.NoError(t, err) | ||
assert.Contains(t, awsgo.StringValueSlice(urls), awsgo.StringValue(queueUrl)) | ||
|
||
err = nukeAllSqsQueues(session, []*string{queueUrl}) | ||
require.NoError(t, err) | ||
|
||
// SQS Queue deletion takes up to 60 seconds to be finished. See https://docs.aws.amazon.com/sdk-for-go/api/service/sqs/#SQS.DeleteQueue | ||
for retry := 0; retry <= 6; retry++ { | ||
urls, err = getAllSqsQueue(session, region, oneHourFromNow) | ||
if err == nil { | ||
break | ||
} | ||
|
||
sleepMessage := "SQS Queue still available. Waiting 10 seconds to check again." | ||
sleepFor := 10 * time.Second | ||
sleepWithMessage(sleepFor, sleepMessage) | ||
sq := SqsQueue{ | ||
Client: mockedSqsQueue{ | ||
DeleteQueueOutput: sqs.DeleteQueueOutput{}, | ||
}, | ||
} | ||
|
||
err := sq.nukeAll([]*string{aws.String("test")}) | ||
require.NoError(t, err) | ||
assert.NotContains(t, awsgo.StringValueSlice(urls), awsgo.StringValue(queueUrl)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters