summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/goamz/goamz/ec2/ec2t_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/goamz/goamz/ec2/ec2t_test.go')
-rw-r--r--vendor/github.com/goamz/goamz/ec2/ec2t_test.go581
1 files changed, 581 insertions, 0 deletions
diff --git a/vendor/github.com/goamz/goamz/ec2/ec2t_test.go b/vendor/github.com/goamz/goamz/ec2/ec2t_test.go
new file mode 100644
index 000000000..37c2e7eb7
--- /dev/null
+++ b/vendor/github.com/goamz/goamz/ec2/ec2t_test.go
@@ -0,0 +1,581 @@
+package ec2_test
+
+import (
+ "fmt"
+ "regexp"
+ "sort"
+
+ "github.com/goamz/goamz/aws"
+ "github.com/goamz/goamz/ec2"
+ "github.com/goamz/goamz/ec2/ec2test"
+ "github.com/goamz/goamz/testutil"
+ . "gopkg.in/check.v1"
+)
+
+// LocalServer represents a local ec2test fake server.
+type LocalServer struct {
+ auth aws.Auth
+ region aws.Region
+ srv *ec2test.Server
+}
+
+func (s *LocalServer) SetUp(c *C) {
+ srv, err := ec2test.NewServer()
+ c.Assert(err, IsNil)
+ c.Assert(srv, NotNil)
+
+ s.srv = srv
+ s.region = aws.Region{EC2Endpoint: srv.URL()}
+}
+
+// LocalServerSuite defines tests that will run
+// against the local ec2test server. It includes
+// selected tests from ClientTests;
+// when the ec2test functionality is sufficient, it should
+// include all of them, and ClientTests can be simply embedded.
+type LocalServerSuite struct {
+ srv LocalServer
+ ServerTests
+ clientTests ClientTests
+}
+
+var _ = Suite(&LocalServerSuite{})
+
+func (s *LocalServerSuite) SetUpSuite(c *C) {
+ s.srv.SetUp(c)
+ s.ServerTests.ec2 = ec2.NewWithClient(s.srv.auth, s.srv.region, testutil.DefaultClient)
+ s.clientTests.ec2 = ec2.NewWithClient(s.srv.auth, s.srv.region, testutil.DefaultClient)
+}
+
+func (s *LocalServerSuite) TestRunAndTerminate(c *C) {
+ s.clientTests.TestRunAndTerminate(c)
+}
+
+func (s *LocalServerSuite) TestSecurityGroups(c *C) {
+ s.clientTests.TestSecurityGroups(c)
+}
+
+// TestUserData is not defined on ServerTests because it
+// requires the ec2test server to function.
+func (s *LocalServerSuite) TestUserData(c *C) {
+ data := make([]byte, 256)
+ for i := range data {
+ data[i] = byte(i)
+ }
+ inst, err := s.ec2.RunInstances(&ec2.RunInstancesOptions{
+ ImageId: imageId,
+ InstanceType: "t1.micro",
+ UserData: data,
+ })
+ c.Assert(err, IsNil)
+ c.Assert(inst, NotNil)
+ c.Assert(inst.Instances[0].DNSName, Equals, inst.Instances[0].InstanceId+".example.com")
+
+ id := inst.Instances[0].InstanceId
+
+ defer s.ec2.TerminateInstances([]string{id})
+
+ tinst := s.srv.srv.Instance(id)
+ c.Assert(tinst, NotNil)
+ c.Assert(tinst.UserData, DeepEquals, data)
+}
+
+// AmazonServerSuite runs the ec2test server tests against a live EC2 server.
+// It will only be activated if the -all flag is specified.
+type AmazonServerSuite struct {
+ srv AmazonServer
+ ServerTests
+}
+
+var _ = Suite(&AmazonServerSuite{})
+
+func (s *AmazonServerSuite) SetUpSuite(c *C) {
+ if !testutil.Amazon {
+ c.Skip("AmazonServerSuite tests not enabled")
+ }
+ s.srv.SetUp(c)
+ s.ServerTests.ec2 = ec2.NewWithClient(s.srv.auth, aws.USEast, testutil.DefaultClient)
+}
+
+// ServerTests defines a set of tests designed to test
+// the ec2test local fake ec2 server.
+// It is not used as a test suite in itself, but embedded within
+// another type.
+type ServerTests struct {
+ ec2 *ec2.EC2
+}
+
+func terminateInstances(c *C, e *ec2.EC2, insts []*ec2.Instance) {
+ var ids []string
+ for _, inst := range insts {
+ if inst != nil {
+ ids = append(ids, inst.InstanceId)
+ }
+ }
+ _, err := e.TerminateInstances(ids)
+ c.Check(err, IsNil, Commentf("%d INSTANCES LEFT RUNNING!!!", len(ids)))
+}
+
+func (s *ServerTests) makeTestGroup(c *C, name, descr string) ec2.SecurityGroup {
+ // Clean it up if a previous test left it around.
+ _, err := s.ec2.DeleteSecurityGroup(ec2.SecurityGroup{Name: name})
+ if err != nil && err.(*ec2.Error).Code != "InvalidGroup.NotFound" {
+ c.Fatalf("delete security group: %v", err)
+ }
+
+ resp, err := s.ec2.CreateSecurityGroup(ec2.SecurityGroup{Name: name, Description: descr})
+ c.Assert(err, IsNil)
+ c.Assert(resp.Name, Equals, name)
+ return resp.SecurityGroup
+}
+
+func (s *ServerTests) TestIPPerms(c *C) {
+ g0 := s.makeTestGroup(c, "goamz-test0", "ec2test group 0")
+ defer s.ec2.DeleteSecurityGroup(g0)
+
+ g1 := s.makeTestGroup(c, "goamz-test1", "ec2test group 1")
+ defer s.ec2.DeleteSecurityGroup(g1)
+
+ resp, err := s.ec2.SecurityGroups([]ec2.SecurityGroup{g0, g1}, nil)
+ c.Assert(err, IsNil)
+ c.Assert(resp.Groups, HasLen, 2)
+ c.Assert(resp.Groups[0].IPPerms, HasLen, 0)
+ c.Assert(resp.Groups[1].IPPerms, HasLen, 0)
+
+ ownerId := resp.Groups[0].OwnerId
+
+ // test some invalid parameters
+ // TODO more
+ _, err = s.ec2.AuthorizeSecurityGroup(g0, []ec2.IPPerm{{
+ Protocol: "tcp",
+ FromPort: 0,
+ ToPort: 1024,
+ SourceIPs: []string{"z127.0.0.1/24"},
+ }})
+ c.Assert(err, NotNil)
+ c.Check(err.(*ec2.Error).Code, Equals, "InvalidPermission.Malformed")
+
+ // Check that AuthorizeSecurityGroup adds the correct authorizations.
+ _, err = s.ec2.AuthorizeSecurityGroup(g0, []ec2.IPPerm{{
+ Protocol: "tcp",
+ FromPort: 2000,
+ ToPort: 2001,
+ SourceIPs: []string{"127.0.0.0/24"},
+ SourceGroups: []ec2.UserSecurityGroup{{
+ Name: g1.Name,
+ }, {
+ Id: g0.Id,
+ }},
+ }, {
+ Protocol: "tcp",
+ FromPort: 2000,
+ ToPort: 2001,
+ SourceIPs: []string{"200.1.1.34/32"},
+ }})
+ c.Assert(err, IsNil)
+
+ resp, err = s.ec2.SecurityGroups([]ec2.SecurityGroup{g0}, nil)
+ c.Assert(err, IsNil)
+ c.Assert(resp.Groups, HasLen, 1)
+ c.Assert(resp.Groups[0].IPPerms, HasLen, 1)
+
+ perm := resp.Groups[0].IPPerms[0]
+ srcg := perm.SourceGroups
+ c.Assert(srcg, HasLen, 2)
+
+ // Normalize so we don't care about returned order.
+ if srcg[0].Name == g1.Name {
+ srcg[0], srcg[1] = srcg[1], srcg[0]
+ }
+ c.Check(srcg[0].Name, Equals, g0.Name)
+ c.Check(srcg[0].Id, Equals, g0.Id)
+ c.Check(srcg[0].OwnerId, Equals, ownerId)
+ c.Check(srcg[1].Name, Equals, g1.Name)
+ c.Check(srcg[1].Id, Equals, g1.Id)
+ c.Check(srcg[1].OwnerId, Equals, ownerId)
+
+ sort.Strings(perm.SourceIPs)
+ c.Check(perm.SourceIPs, DeepEquals, []string{"127.0.0.0/24", "200.1.1.34/32"})
+
+ // Check that we can't delete g1 (because g0 is using it)
+ _, err = s.ec2.DeleteSecurityGroup(g1)
+ c.Assert(err, NotNil)
+ c.Check(err.(*ec2.Error).Code, Equals, "InvalidGroup.InUse")
+
+ _, err = s.ec2.RevokeSecurityGroup(g0, []ec2.IPPerm{{
+ Protocol: "tcp",
+ FromPort: 2000,
+ ToPort: 2001,
+ SourceGroups: []ec2.UserSecurityGroup{{Id: g1.Id}},
+ }, {
+ Protocol: "tcp",
+ FromPort: 2000,
+ ToPort: 2001,
+ SourceIPs: []string{"200.1.1.34/32"},
+ }})
+ c.Assert(err, IsNil)
+
+ resp, err = s.ec2.SecurityGroups([]ec2.SecurityGroup{g0}, nil)
+ c.Assert(err, IsNil)
+ c.Assert(resp.Groups, HasLen, 1)
+ c.Assert(resp.Groups[0].IPPerms, HasLen, 1)
+
+ perm = resp.Groups[0].IPPerms[0]
+ srcg = perm.SourceGroups
+ c.Assert(srcg, HasLen, 1)
+ c.Check(srcg[0].Name, Equals, g0.Name)
+ c.Check(srcg[0].Id, Equals, g0.Id)
+ c.Check(srcg[0].OwnerId, Equals, ownerId)
+
+ c.Check(perm.SourceIPs, DeepEquals, []string{"127.0.0.0/24"})
+
+ // We should be able to delete g1 now because we've removed its only use.
+ _, err = s.ec2.DeleteSecurityGroup(g1)
+ c.Assert(err, IsNil)
+
+ _, err = s.ec2.DeleteSecurityGroup(g0)
+ c.Assert(err, IsNil)
+
+ f := ec2.NewFilter()
+ f.Add("group-id", g0.Id, g1.Id)
+ resp, err = s.ec2.SecurityGroups(nil, f)
+ c.Assert(err, IsNil)
+ c.Assert(resp.Groups, HasLen, 0)
+}
+
+func (s *ServerTests) TestDuplicateIPPerm(c *C) {
+ name := "goamz-test"
+ descr := "goamz security group for tests"
+
+ // Clean it up, if a previous test left it around and avoid leaving it around.
+ s.ec2.DeleteSecurityGroup(ec2.SecurityGroup{Name: name})
+ defer s.ec2.DeleteSecurityGroup(ec2.SecurityGroup{Name: name})
+
+ resp1, err := s.ec2.CreateSecurityGroup(ec2.SecurityGroup{Name: name, Description: descr})
+ c.Assert(err, IsNil)
+ c.Assert(resp1.Name, Equals, name)
+
+ perms := []ec2.IPPerm{{
+ Protocol: "tcp",
+ FromPort: 200,
+ ToPort: 1024,
+ SourceIPs: []string{"127.0.0.1/24"},
+ }, {
+ Protocol: "tcp",
+ FromPort: 0,
+ ToPort: 100,
+ SourceIPs: []string{"127.0.0.1/24"},
+ }}
+
+ _, err = s.ec2.AuthorizeSecurityGroup(ec2.SecurityGroup{Name: name}, perms[0:1])
+ c.Assert(err, IsNil)
+
+ _, err = s.ec2.AuthorizeSecurityGroup(ec2.SecurityGroup{Name: name}, perms[0:2])
+ c.Assert(err, ErrorMatches, `.*\(InvalidPermission.Duplicate\)`)
+}
+
+type filterSpec struct {
+ name string
+ values []string
+}
+
+func (s *ServerTests) TestInstanceFiltering(c *C) {
+ groupResp, err := s.ec2.CreateSecurityGroup(ec2.SecurityGroup{Name: sessionName("testgroup1"), Description: "testgroup one description"})
+ c.Assert(err, IsNil)
+ group1 := groupResp.SecurityGroup
+ defer s.ec2.DeleteSecurityGroup(group1)
+
+ groupResp, err = s.ec2.CreateSecurityGroup(ec2.SecurityGroup{Name: sessionName("testgroup2"), Description: "testgroup two description"})
+ c.Assert(err, IsNil)
+ group2 := groupResp.SecurityGroup
+ defer s.ec2.DeleteSecurityGroup(group2)
+
+ insts := make([]*ec2.Instance, 3)
+ inst, err := s.ec2.RunInstances(&ec2.RunInstancesOptions{
+ MinCount: 2,
+ ImageId: imageId,
+ InstanceType: "t1.micro",
+ SecurityGroups: []ec2.SecurityGroup{group1},
+ })
+ c.Assert(err, IsNil)
+ insts[0] = &inst.Instances[0]
+ insts[1] = &inst.Instances[1]
+ defer terminateInstances(c, s.ec2, insts)
+
+ imageId2 := "ami-e358958a" // Natty server, i386, EBS store
+ inst, err = s.ec2.RunInstances(&ec2.RunInstancesOptions{
+ ImageId: imageId2,
+ InstanceType: "t1.micro",
+ SecurityGroups: []ec2.SecurityGroup{group2},
+ })
+ c.Assert(err, IsNil)
+ insts[2] = &inst.Instances[0]
+
+ ids := func(indices ...int) (instIds []string) {
+ for _, index := range indices {
+ instIds = append(instIds, insts[index].InstanceId)
+ }
+ return
+ }
+
+ tests := []struct {
+ about string
+ instanceIds []string // instanceIds argument to Instances method.
+ filters []filterSpec // filters argument to Instances method.
+ resultIds []string // set of instance ids of expected results.
+ allowExtra bool // resultIds may be incomplete.
+ err string // expected error.
+ }{
+ {
+ about: "check that Instances returns all instances",
+ resultIds: ids(0, 1, 2),
+ allowExtra: true,
+ }, {
+ about: "check that specifying two instance ids returns them",
+ instanceIds: ids(0, 2),
+ resultIds: ids(0, 2),
+ }, {
+ about: "check that specifying a non-existent instance id gives an error",
+ instanceIds: append(ids(0), "i-deadbeef"),
+ err: `.*\(InvalidInstanceID\.NotFound\)`,
+ }, {
+ about: "check that a filter allowed both instances returns both of them",
+ filters: []filterSpec{
+ {"instance-id", ids(0, 2)},
+ },
+ resultIds: ids(0, 2),
+ }, {
+ about: "check that a filter allowing only one instance returns it",
+ filters: []filterSpec{
+ {"instance-id", ids(1)},
+ },
+ resultIds: ids(1),
+ }, {
+ about: "check that a filter allowing no instances returns none",
+ filters: []filterSpec{
+ {"instance-id", []string{"i-deadbeef12345"}},
+ },
+ }, {
+ about: "check that filtering on group id works",
+ filters: []filterSpec{
+ {"group-id", []string{group1.Id}},
+ },
+ resultIds: ids(0, 1),
+ }, {
+ about: "check that filtering on group name works",
+ filters: []filterSpec{
+ {"group-name", []string{group1.Name}},
+ },
+ resultIds: ids(0, 1),
+ }, {
+ about: "check that filtering on image id works",
+ filters: []filterSpec{
+ {"image-id", []string{imageId}},
+ },
+ resultIds: ids(0, 1),
+ allowExtra: true,
+ }, {
+ about: "combination filters 1",
+ filters: []filterSpec{
+ {"image-id", []string{imageId, imageId2}},
+ {"group-name", []string{group1.Name}},
+ },
+ resultIds: ids(0, 1),
+ }, {
+ about: "combination filters 2",
+ filters: []filterSpec{
+ {"image-id", []string{imageId2}},
+ {"group-name", []string{group1.Name}},
+ },
+ },
+ }
+ for i, t := range tests {
+ c.Logf("%d. %s", i, t.about)
+ var f *ec2.Filter
+ if t.filters != nil {
+ f = ec2.NewFilter()
+ for _, spec := range t.filters {
+ f.Add(spec.name, spec.values...)
+ }
+ }
+ resp, err := s.ec2.DescribeInstances(t.instanceIds, f)
+ if t.err != "" {
+ c.Check(err, ErrorMatches, t.err)
+ continue
+ }
+ c.Assert(err, IsNil)
+ insts := make(map[string]*ec2.Instance)
+ for _, r := range resp.Reservations {
+ for j := range r.Instances {
+ inst := &r.Instances[j]
+ c.Check(insts[inst.InstanceId], IsNil, Commentf("duplicate instance id: %q", inst.InstanceId))
+ insts[inst.InstanceId] = inst
+ }
+ }
+ if !t.allowExtra {
+ c.Check(insts, HasLen, len(t.resultIds), Commentf("expected %d instances got %#v", len(t.resultIds), insts))
+ }
+ for j, id := range t.resultIds {
+ c.Check(insts[id], NotNil, Commentf("instance id %d (%q) not found; got %#v", j, id, insts))
+ }
+ }
+}
+
+func idsOnly(gs []ec2.SecurityGroup) []ec2.SecurityGroup {
+ for i := range gs {
+ gs[i].Name = ""
+ }
+ return gs
+}
+
+func namesOnly(gs []ec2.SecurityGroup) []ec2.SecurityGroup {
+ for i := range gs {
+ gs[i].Id = ""
+ }
+ return gs
+}
+
+func (s *ServerTests) TestGroupFiltering(c *C) {
+ g := make([]ec2.SecurityGroup, 4)
+ for i := range g {
+ resp, err := s.ec2.CreateSecurityGroup(ec2.SecurityGroup{Name: sessionName(fmt.Sprintf("testgroup%d", i)), Description: fmt.Sprintf("testdescription%d", i)})
+ c.Assert(err, IsNil)
+ g[i] = resp.SecurityGroup
+ c.Logf("group %d: %v", i, g[i])
+ defer s.ec2.DeleteSecurityGroup(g[i])
+ }
+
+ perms := [][]ec2.IPPerm{
+ {{
+ Protocol: "tcp",
+ FromPort: 100,
+ ToPort: 200,
+ SourceIPs: []string{"1.2.3.4/32"},
+ }},
+ {{
+ Protocol: "tcp",
+ FromPort: 200,
+ ToPort: 300,
+ SourceGroups: []ec2.UserSecurityGroup{{Id: g[1].Id}},
+ }},
+ {{
+ Protocol: "udp",
+ FromPort: 200,
+ ToPort: 400,
+ SourceGroups: []ec2.UserSecurityGroup{{Id: g[1].Id}},
+ }},
+ }
+ for i, ps := range perms {
+ _, err := s.ec2.AuthorizeSecurityGroup(g[i], ps)
+ c.Assert(err, IsNil)
+ }
+
+ groups := func(indices ...int) (gs []ec2.SecurityGroup) {
+ for _, index := range indices {
+ gs = append(gs, g[index])
+ }
+ return
+ }
+
+ type groupTest struct {
+ about string
+ groups []ec2.SecurityGroup // groupIds argument to SecurityGroups method.
+ filters []filterSpec // filters argument to SecurityGroups method.
+ results []ec2.SecurityGroup // set of expected result groups.
+ allowExtra bool // specified results may be incomplete.
+ err string // expected error.
+ }
+ filterCheck := func(name, val string, gs []ec2.SecurityGroup) groupTest {
+ return groupTest{
+ about: "filter check " + name,
+ filters: []filterSpec{{name, []string{val}}},
+ results: gs,
+ allowExtra: true,
+ }
+ }
+ tests := []groupTest{
+ {
+ about: "check that SecurityGroups returns all groups",
+ results: groups(0, 1, 2, 3),
+ allowExtra: true,
+ }, {
+ about: "check that specifying two group ids returns them",
+ groups: idsOnly(groups(0, 2)),
+ results: groups(0, 2),
+ }, {
+ about: "check that specifying names only works",
+ groups: namesOnly(groups(0, 2)),
+ results: groups(0, 2),
+ }, {
+ about: "check that specifying a non-existent group id gives an error",
+ groups: append(groups(0), ec2.SecurityGroup{Id: "sg-eeeeeeeee"}),
+ err: `.*\(InvalidGroup\.NotFound\)`,
+ }, {
+ about: "check that a filter allowed two groups returns both of them",
+ filters: []filterSpec{
+ {"group-id", []string{g[0].Id, g[2].Id}},
+ },
+ results: groups(0, 2),
+ },
+ {
+ about: "check that the previous filter works when specifying a list of ids",
+ groups: groups(1, 2),
+ filters: []filterSpec{
+ {"group-id", []string{g[0].Id, g[2].Id}},
+ },
+ results: groups(2),
+ }, {
+ about: "check that a filter allowing no groups returns none",
+ filters: []filterSpec{
+ {"group-id", []string{"sg-eeeeeeeee"}},
+ },
+ },
+ filterCheck("description", "testdescription1", groups(1)),
+ filterCheck("group-name", g[2].Name, groups(2)),
+ filterCheck("ip-permission.cidr", "1.2.3.4/32", groups(0)),
+ filterCheck("ip-permission.group-name", g[1].Name, groups(1, 2)),
+ filterCheck("ip-permission.protocol", "udp", groups(2)),
+ filterCheck("ip-permission.from-port", "200", groups(1, 2)),
+ filterCheck("ip-permission.to-port", "200", groups(0)),
+ // TODO owner-id
+ }
+ for i, t := range tests {
+ c.Logf("%d. %s", i, t.about)
+ var f *ec2.Filter
+ if t.filters != nil {
+ f = ec2.NewFilter()
+ for _, spec := range t.filters {
+ f.Add(spec.name, spec.values...)
+ }
+ }
+ resp, err := s.ec2.SecurityGroups(t.groups, f)
+ if t.err != "" {
+ c.Check(err, ErrorMatches, t.err)
+ continue
+ }
+ c.Assert(err, IsNil)
+ groups := make(map[string]*ec2.SecurityGroup)
+ for j := range resp.Groups {
+ group := &resp.Groups[j].SecurityGroup
+ c.Check(groups[group.Id], IsNil, Commentf("duplicate group id: %q", group.Id))
+
+ groups[group.Id] = group
+ }
+ // If extra groups may be returned, eliminate all groups that
+ // we did not create in this session apart from the default group.
+ if t.allowExtra {
+ namePat := regexp.MustCompile(sessionName("testgroup[0-9]"))
+ for id, g := range groups {
+ if !namePat.MatchString(g.Name) {
+ delete(groups, id)
+ }
+ }
+ }
+ c.Check(groups, HasLen, len(t.results))
+ for j, g := range t.results {
+ rg := groups[g.Id]
+ c.Assert(rg, NotNil, Commentf("group %d (%v) not found; got %#v", j, g, groups))
+ c.Check(rg.Name, Equals, g.Name, Commentf("group %d (%v)", j, g))
+ }
+ }
+}