github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/juju/subnet/package_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package subnet_test 5 6 import ( 7 "net" 8 stdtesting "testing" 9 10 "github.com/juju/cmd" 11 "github.com/juju/names" 12 "github.com/juju/testing" 13 jc "github.com/juju/testing/checkers" 14 "github.com/juju/utils/featureflag" 15 gc "gopkg.in/check.v1" 16 17 "github.com/juju/juju/apiserver/params" 18 "github.com/juju/juju/cmd/juju/subnet" 19 "github.com/juju/juju/feature" 20 "github.com/juju/juju/network" 21 coretesting "github.com/juju/juju/testing" 22 ) 23 24 func TestPackage(t *stdtesting.T) { 25 gc.TestingT(t) 26 } 27 28 // BaseSubnetSuite is used for embedding in other suites. 29 type BaseSubnetSuite struct { 30 coretesting.FakeJujuXDGDataHomeSuite 31 coretesting.BaseSuite 32 33 command cmd.Command 34 api *StubAPI 35 } 36 37 var _ = gc.Suite(&BaseSubnetSuite{}) 38 39 func (s *BaseSubnetSuite) SetUpSuite(c *gc.C) { 40 s.FakeJujuXDGDataHomeSuite.SetUpSuite(c) 41 s.BaseSuite.SetUpSuite(c) 42 } 43 44 func (s *BaseSubnetSuite) TearDownSuite(c *gc.C) { 45 s.BaseSuite.TearDownSuite(c) 46 s.FakeJujuXDGDataHomeSuite.TearDownSuite(c) 47 } 48 49 func (s *BaseSubnetSuite) SetUpTest(c *gc.C) { 50 // If any post-MVP command suite enabled the flag, keep it. 51 hasFeatureFlag := featureflag.Enabled(feature.PostNetCLIMVP) 52 53 s.BaseSuite.SetUpTest(c) 54 s.FakeJujuXDGDataHomeSuite.SetUpTest(c) 55 56 if hasFeatureFlag { 57 s.BaseSuite.SetFeatureFlags(feature.PostNetCLIMVP) 58 } 59 60 s.api = NewStubAPI() 61 c.Assert(s.api, gc.NotNil) 62 63 // All subcommand suites embedding this one should initialize 64 // s.command immediately after calling this method! 65 } 66 67 func (s *BaseSubnetSuite) TearDownTest(c *gc.C) { 68 s.BaseSuite.TearDownTest(c) 69 s.FakeJujuXDGDataHomeSuite.TearDownTest(c) 70 } 71 72 // RunCommand executes the s.command passing any args 73 // and returning the stdout and stderr output as strings, as well as 74 // any error. 75 func (s *BaseSubnetSuite) RunCommand(c *gc.C, args ...string) (string, string, error) { 76 if s.command == nil { 77 panic("command is nil") 78 } 79 ctx, err := coretesting.RunCommand(c, s.command, args...) 80 if ctx != nil { 81 return coretesting.Stdout(ctx), coretesting.Stderr(ctx), err 82 } 83 return "", "", err 84 } 85 86 // AssertRunFails is a shortcut for calling RunCommand with the 87 // passed args then asserting the output is empty and the error is as 88 // expected, finally returning the error. 89 func (s *BaseSubnetSuite) AssertRunFails(c *gc.C, expectErr string, args ...string) error { 90 stdout, stderr, err := s.RunCommand(c, args...) 91 c.Assert(err, gc.ErrorMatches, expectErr) 92 c.Assert(stdout, gc.Equals, "") 93 c.Assert(stderr, gc.Equals, "") 94 return err 95 } 96 97 // AssertRunSucceeds is a shortcut for calling RunCommand with 98 // the passed args then asserting the stderr output matches 99 // expectStderr, stdout is equal to expectStdout, and the error is 100 // nil. 101 func (s *BaseSubnetSuite) AssertRunSucceeds(c *gc.C, expectStderr, expectStdout string, args ...string) { 102 stdout, stderr, err := s.RunCommand(c, args...) 103 c.Assert(err, jc.ErrorIsNil) 104 c.Assert(stdout, gc.Equals, expectStdout) 105 c.Assert(stderr, gc.Matches, expectStderr) 106 } 107 108 // Strings makes tests taking a slice of strings slightly easier to 109 // write: e.g. s.Strings("foo", "bar") vs. []string{"foo", "bar"}. 110 func (s *BaseSubnetSuite) Strings(values ...string) []string { 111 return values 112 } 113 114 // StubAPI defines a testing stub for the SubnetAPI interface. 115 type StubAPI struct { 116 *testing.Stub 117 118 Subnets []params.Subnet 119 Spaces []names.Tag 120 Zones []string 121 } 122 123 var _ subnet.SubnetAPI = (*StubAPI)(nil) 124 125 // NewStubAPI creates a StubAPI suitable for passing to 126 // subnet.New*Command(). 127 func NewStubAPI() *StubAPI { 128 subnets := []params.Subnet{{ 129 // IPv4 subnet. 130 CIDR: "10.20.0.0/24", 131 ProviderId: "subnet-foo", 132 Life: params.Alive, 133 SpaceTag: "space-public", 134 Zones: []string{"zone1", "zone2"}, 135 StaticRangeLowIP: net.ParseIP("10.20.0.10"), 136 StaticRangeHighIP: net.ParseIP("10.20.0.100"), 137 }, { 138 // IPv6 subnet. 139 CIDR: "2001:db8::/32", 140 ProviderId: "subnet-bar", 141 Life: params.Dying, 142 SpaceTag: "space-dmz", 143 Zones: []string{"zone2"}, 144 }, { 145 // IPv4 VLAN subnet. 146 CIDR: "10.10.0.0/16", 147 Life: params.Dead, 148 SpaceTag: "space-vlan-42", 149 Zones: []string{"zone1"}, 150 VLANTag: 42, 151 }} 152 return &StubAPI{ 153 Stub: &testing.Stub{}, 154 Zones: []string{"zone1", "zone2"}, 155 Subnets: subnets, 156 Spaces: []names.Tag{ 157 names.NewSpaceTag("default"), 158 names.NewSpaceTag("public"), 159 names.NewSpaceTag("dmz"), 160 names.NewSpaceTag("vlan-42"), 161 }, 162 } 163 } 164 165 func (sa *StubAPI) Close() error { 166 sa.MethodCall(sa, "Close") 167 return sa.NextErr() 168 } 169 170 func (sa *StubAPI) AllZones() ([]string, error) { 171 sa.MethodCall(sa, "AllZones") 172 if err := sa.NextErr(); err != nil { 173 return nil, err 174 } 175 return sa.Zones, nil 176 } 177 178 func (sa *StubAPI) AllSpaces() ([]names.Tag, error) { 179 sa.MethodCall(sa, "AllSpaces") 180 if err := sa.NextErr(); err != nil { 181 return nil, err 182 } 183 return sa.Spaces, nil 184 } 185 186 func (sa *StubAPI) CreateSubnet(subnetCIDR names.SubnetTag, spaceTag names.SpaceTag, zones []string, isPublic bool) error { 187 sa.MethodCall(sa, "CreateSubnet", subnetCIDR, spaceTag, zones, isPublic) 188 return sa.NextErr() 189 } 190 191 func (sa *StubAPI) AddSubnet(cidr names.SubnetTag, id network.Id, spaceTag names.SpaceTag, zones []string) error { 192 sa.MethodCall(sa, "AddSubnet", cidr, id, spaceTag, zones) 193 return sa.NextErr() 194 } 195 196 func (sa *StubAPI) RemoveSubnet(subnetCIDR names.SubnetTag) error { 197 sa.MethodCall(sa, "RemoveSubnet", subnetCIDR) 198 return sa.NextErr() 199 } 200 201 func (sa *StubAPI) ListSubnets(withSpace *names.SpaceTag, withZone string) ([]params.Subnet, error) { 202 if withSpace == nil { 203 // Due to the way CheckCall works (using jc.DeepEquals 204 // internally), we need to pass an explicit nil here, rather 205 // than a pointer to a names.SpaceTag pointing to nil. 206 sa.MethodCall(sa, "ListSubnets", nil, withZone) 207 } else { 208 sa.MethodCall(sa, "ListSubnets", withSpace, withZone) 209 } 210 if err := sa.NextErr(); err != nil { 211 return nil, err 212 } 213 return sa.Subnets, nil 214 }