-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
aws: Add unit tests and acceptance tests for SNS topics.
- Loading branch information
Showing
2 changed files
with
250 additions
and
0 deletions.
There are no files selected for viewing
149 changes: 149 additions & 0 deletions
149
builtin/providers/aws/resource_aws_sns_topic_seeker_test.go
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 |
---|---|---|
@@ -0,0 +1,149 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
"time" | ||
|
||
"github.com/awslabs/aws-sdk-go/aws" | ||
"github.com/awslabs/aws-sdk-go/service/sns" | ||
) | ||
|
||
// tokenMap mimics paging of topic results. | ||
var tokenMap = map[string]*sns.ListTopicsOutput{ | ||
"tokenA": &sns.ListTopicsOutput{ | ||
Topics: []*sns.Topic{ | ||
&sns.Topic{ | ||
TopicARN: aws.String("arn:aws:sns:us-east-1:123456789012:foo"), | ||
}, | ||
}, | ||
NextToken: aws.String("tokenB"), | ||
}, | ||
"tokenB": &sns.ListTopicsOutput{ | ||
Topics: []*sns.Topic{ | ||
&sns.Topic{ | ||
TopicARN: aws.String("arn:aws:sns:us-east-1:123456789012:bar"), | ||
}, | ||
}, | ||
NextToken: aws.String("tokenC"), | ||
}, | ||
"tokenC": &sns.ListTopicsOutput{ | ||
Topics: []*sns.Topic{ | ||
&sns.Topic{ | ||
TopicARN: aws.String("arn:aws:sns:us-east-1:123456789012:baz"), | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
// ltErr mimics a ListTopics error | ||
var ltErr = fmt.Errorf("Got an error listing topics!") | ||
|
||
// snsConnMock implements topicLister, so we can mock result paging. | ||
type snsConnMock struct { | ||
topics map[string]*sns.ListTopicsOutput | ||
err error | ||
} | ||
|
||
// ListTopics returns paged results out of the tokenMap. | ||
func (s *snsConnMock) ListTopics(input *sns.ListTopicsInput) (*sns.ListTopicsOutput, error) { | ||
var emptyResult sns.ListTopicsOutput | ||
|
||
switch { | ||
case s.topics == nil: | ||
// return an empty result | ||
return &emptyResult, nil | ||
case s.err != nil: | ||
// return a mocked response error | ||
return nil, s.err | ||
case input.NextToken == nil: | ||
// we're the first call, return tokenA | ||
return tokenMap["tokenA"], nil | ||
default: | ||
// we're somewhere in the pagination. | ||
return tokenMap[*input.NextToken], nil | ||
} | ||
} | ||
|
||
func Test_snsTopicSeeker_emit(t *testing.T) { | ||
s := &snsTopicSeeker{ | ||
arns: make(chan string), | ||
} | ||
topic := &sns.Topic{ | ||
TopicARN: aws.String("arn:aws:sns:us-east-1:123456789012:foo"), | ||
} | ||
|
||
go s.emit(topic) | ||
|
||
// arns is a synchronous channel, so we can't simply block on a read if | ||
// we're trying to test something sent to it. Instead, use a timeout. | ||
timeout := make(chan bool, 1) | ||
go func() { | ||
time.Sleep(10 * time.Second) | ||
timeout <- true | ||
}() | ||
|
||
select { | ||
case <-s.arns: | ||
return | ||
case <-timeout: | ||
t.Fatalf("emit didn't send a topic to the 'arns' channel!") | ||
} | ||
} | ||
|
||
func Test_snsTopicSeeker_errorf(t *testing.T) { | ||
s := &snsTopicSeeker{ | ||
errc: make(chan error, 1), | ||
} | ||
|
||
// errc is buffered. No need for a goroutine here. | ||
s.errorf(fmt.Errorf("This is an error")) | ||
|
||
select { | ||
case <-s.errc: | ||
return | ||
default: | ||
} | ||
t.Fatal("errorf didn't send an error to the 'errc' channel!") | ||
} | ||
|
||
func Test_snsTopicSeeker(t *testing.T) { | ||
for _, ts := range []struct { | ||
name string | ||
lister *snsConnMock | ||
shouldErr bool | ||
wantedLen int | ||
}{ | ||
{"paginated response", &snsConnMock{topics: tokenMap}, false, 3}, | ||
{"error response", &snsConnMock{topics: tokenMap, err: ltErr}, true, 0}, | ||
{"no topics response", &snsConnMock{}, false, 0}, | ||
} { | ||
// build the seeker | ||
s := &snsTopicSeeker{ | ||
lister: ts.lister, | ||
arns: make(chan string), | ||
errc: make(chan error, 1), | ||
} | ||
|
||
// run the seeker | ||
go s.run() | ||
|
||
// walk our response | ||
var walkedArns []string | ||
for arn := range s.arns { | ||
walkedArns = append(walkedArns, arn) | ||
} | ||
|
||
if len(walkedArns) != ts.wantedLen { | ||
t.Fatalf("%s: expected %d ARNs; got %d", ts.name, ts.wantedLen, len(walkedArns)) | ||
} | ||
|
||
err := <-s.errc | ||
if ts.shouldErr && err == nil { | ||
t.Fatalf("%s: expected error; didn't get one", ts.name) | ||
} | ||
if !ts.shouldErr && err != nil { | ||
t.Fatalf("%s: expected no error; got one: %s", ts.name, err) | ||
} | ||
} | ||
} |
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 |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func TestAccSnsTopic(t *testing.T) { | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccAwsSnsTopicDestroy, | ||
Steps: []resource.TestStep{ | ||
resource.TestStep{ | ||
Config: testAccAwsSnsTopicConfig, | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccAwsSnsTopic( | ||
"aws_sns_topic.foo", | ||
), | ||
), | ||
}, | ||
resource.TestStep{ | ||
Config: testAccAwsSnsTopicConfigUpdate, | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccAwsSnsTopic( | ||
"aws_sns_topic.foo", | ||
), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccAwsSnsTopicDestroy(s *terraform.State) error { | ||
if len(s.RootModule().Resources) > 0 { | ||
return fmt.Errorf("Expected all resources to be gone, but found: %#v", s.RootModule().Resources) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func testAccAwsSnsTopic(snsTopicResource string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
rs, ok := s.RootModule().Resources[snsTopicResource] | ||
if !ok { | ||
return fmt.Errorf("Not found: %s", snsTopicResource) | ||
} | ||
|
||
if rs.Primary.ID == "" { | ||
return fmt.Errorf("No ID is set") | ||
} | ||
topic, ok := s.RootModule().Resources[snsTopicResource] | ||
if !ok { | ||
return fmt.Errorf("Not found: %s", snsTopicResource) | ||
} | ||
|
||
snsconn := testAccProvider.Meta().(*AWSClient).snsconn | ||
|
||
match, err := seekSnsTopic(topic.Primary.ID, snsconn) | ||
if err != nil { | ||
return err | ||
} | ||
if match == "" { | ||
return fmt.Errorf("Not found in AWS: %s", topic) | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
const testAccAwsSnsTopicConfig = ` | ||
resource "aws_sns_topic" "foo" { | ||
name = "foo" | ||
} | ||
` | ||
|
||
// Change the name but leave the resource name the same. | ||
const testAccAwsSnsTopicConfigUpdate = ` | ||
resource "aws_sns_topic" "foo" { | ||
name = "bar" | ||
} | ||
` | ||
|
||
func Test_parseSnsTopicArn(t *testing.T) { | ||
for _, ts := range []struct { | ||
arn string | ||
wanted string | ||
}{ | ||
{"arn:aws:sns:us-east-1:123456789012:foo", "foo"}, | ||
{"arn:aws:sns:us-west-1:123456789012:bar", "bar"}, | ||
{"arn:aws:sns:us-east-1:123456789012:baz", "baz"}, | ||
} { | ||
got := parseSnsTopicArn(ts.arn) | ||
if got != ts.wanted { | ||
t.Fatalf("got %s; wanted %s", got, ts.wanted) | ||
} | ||
} | ||
} |