github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/cmd/juju/space/package_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package space_test 5 6 import ( 7 "net" 8 "regexp" 9 stdtesting "testing" 10 11 "github.com/juju/cmd" 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/space" 19 "github.com/juju/juju/feature" 20 coretesting "github.com/juju/juju/testing" 21 ) 22 23 func TestPackage(t *stdtesting.T) { 24 gc.TestingT(t) 25 } 26 27 // BaseSpaceSuite is used for embedding in other suites. 28 type BaseSpaceSuite struct { 29 coretesting.FakeJujuHomeSuite 30 coretesting.BaseSuite 31 32 superCmd cmd.Command 33 command cmd.Command 34 api *StubAPI 35 } 36 37 var _ = gc.Suite(&BaseSpaceSuite{}) 38 39 func (s *BaseSpaceSuite) SetUpTest(c *gc.C) { 40 // If any post-MVP command suite enabled the flag, keep it. 41 hasFeatureFlag := featureflag.Enabled(feature.PostNetCLIMVP) 42 43 s.BaseSuite.SetUpTest(c) 44 s.FakeJujuHomeSuite.SetUpTest(c) 45 46 if hasFeatureFlag { 47 s.BaseSuite.SetFeatureFlags(feature.PostNetCLIMVP) 48 } 49 50 s.superCmd = space.NewSuperCommand() 51 c.Assert(s.superCmd, gc.NotNil) 52 53 s.api = NewStubAPI() 54 c.Assert(s.api, gc.NotNil) 55 56 // All subcommand suites embedding this one should initialize 57 // s.command immediately after calling this method! 58 } 59 60 // RunSuperCommand executes the super command passing any args and 61 // returning the stdout and stderr output as strings, as well as any 62 // error. If s.command is set, the subcommand's name will be passed as 63 // first argument. 64 func (s *BaseSpaceSuite) RunSuperCommand(c *gc.C, args ...string) (string, string, error) { 65 if s.command != nil { 66 args = append([]string{s.command.Info().Name}, args...) 67 } 68 ctx, err := coretesting.RunCommand(c, s.superCmd, args...) 69 if ctx != nil { 70 return coretesting.Stdout(ctx), coretesting.Stderr(ctx), err 71 } 72 return "", "", err 73 } 74 75 // RunSubCommand executes the s.command subcommand passing any args 76 // and returning the stdout and stderr output as strings, as well as 77 // any error. 78 func (s *BaseSpaceSuite) RunSubCommand(c *gc.C, args ...string) (string, string, error) { 79 if s.command == nil { 80 panic("subcommand is nil") 81 } 82 ctx, err := coretesting.RunCommand(c, s.command, args...) 83 if ctx != nil { 84 return coretesting.Stdout(ctx), coretesting.Stderr(ctx), err 85 } 86 return "", "", err 87 } 88 89 // AssertRunSpacesNotSupported is a shortcut for calling RunSubCommand with the 90 // passed args then asserting the output is empty and the error is the 91 // spaces not supported, finally returning the error. 92 func (s *BaseSpaceSuite) AssertRunSpacesNotSupported(c *gc.C, expectErr string, args ...string) error { 93 stdout, stderr, err := s.RunSubCommand(c, args...) 94 c.Assert(err, gc.ErrorMatches, expectErr) 95 c.Assert(stdout, gc.Equals, "") 96 c.Assert(stderr, gc.Equals, expectErr+"\n") 97 return err 98 } 99 100 // AssertRunFails is a shortcut for calling RunSubCommand with the 101 // passed args then asserting the output is empty and the error is as 102 // expected, finally returning the error. 103 func (s *BaseSpaceSuite) AssertRunFails(c *gc.C, expectErr string, args ...string) error { 104 stdout, stderr, err := s.RunSubCommand(c, args...) 105 c.Assert(err, gc.ErrorMatches, expectErr) 106 c.Assert(stdout, gc.Equals, "") 107 c.Assert(stderr, gc.Equals, "") 108 return err 109 } 110 111 // AssertRunSucceeds is a shortcut for calling RunSuperCommand with 112 // the passed args then asserting the stderr output matches 113 // expectStderr, stdout is equal to expectStdout, and the error is 114 // nil. 115 func (s *BaseSpaceSuite) AssertRunSucceeds(c *gc.C, expectStderr, expectStdout string, args ...string) { 116 stdout, stderr, err := s.RunSubCommand(c, args...) 117 c.Assert(err, jc.ErrorIsNil) 118 c.Assert(stdout, gc.Equals, expectStdout) 119 c.Assert(stderr, gc.Matches, expectStderr) 120 } 121 122 // TestHelp runs the command with --help as argument and verifies the 123 // output. 124 func (s *BaseSpaceSuite) TestHelp(c *gc.C) { 125 stderr, stdout, err := s.RunSuperCommand(c, "--help") 126 c.Assert(err, jc.ErrorIsNil) 127 c.Check(stdout, gc.Equals, "") 128 c.Check(stderr, gc.Not(gc.Equals), "") 129 130 // If s.command is set, use it instead of s.superCmd. 131 cmdInfo := s.superCmd.Info() 132 var expected string 133 if s.command != nil { 134 // Subcommands embed EnvCommandBase 135 cmdInfo = s.command.Info() 136 expected = "(?sm).*^usage: juju space " + 137 regexp.QuoteMeta(cmdInfo.Name) + 138 `( \[options\])? ` + regexp.QuoteMeta(cmdInfo.Args) + ".+" 139 } else { 140 expected = "(?sm).*^usage: juju space" + 141 `( \[options\])? ` + regexp.QuoteMeta(cmdInfo.Args) + ".+" 142 } 143 c.Check(cmdInfo, gc.NotNil) 144 c.Check(stderr, gc.Matches, expected) 145 146 expected = "(?sm).*^purpose: " + regexp.QuoteMeta(cmdInfo.Purpose) + "$.*" 147 c.Check(stderr, gc.Matches, expected) 148 149 expected = "(?sm).*^" + regexp.QuoteMeta(cmdInfo.Doc) + "$.*" 150 c.Check(stderr, gc.Matches, expected) 151 } 152 153 // Strings is makes tests taking a slice of strings slightly easier to 154 // write: e.g. s.Strings("foo", "bar") vs. []string{"foo", "bar"}. 155 func (s *BaseSpaceSuite) Strings(values ...string) []string { 156 return values 157 } 158 159 // StubAPI defines a testing stub for the SpaceAPI interface. 160 type StubAPI struct { 161 *testing.Stub 162 163 Spaces []params.Space 164 Subnets []params.Subnet 165 } 166 167 var _ space.SpaceAPI = (*StubAPI)(nil) 168 169 // NewStubAPI creates a StubAPI suitable for passing to 170 // space.New*Command(). 171 func NewStubAPI() *StubAPI { 172 subnets := []params.Subnet{{ 173 // IPv6 subnet. 174 CIDR: "2001:db8::/32", 175 ProviderId: "subnet-public", 176 Life: params.Dying, 177 SpaceTag: "space-space1", 178 Zones: []string{"zone2"}, 179 }, { 180 // Invalid subnet (just for 100% coverage, otherwise it can't happen). 181 CIDR: "invalid", 182 ProviderId: "no-such", 183 SpaceTag: "space-space1", 184 Zones: []string{"zone1"}, 185 }, { 186 // IPv4 subnet. 187 CIDR: "10.1.2.0/24", 188 ProviderId: "subnet-private", 189 Life: params.Alive, 190 SpaceTag: "space-space2", 191 Zones: []string{"zone1", "zone2"}, 192 StaticRangeLowIP: net.ParseIP("10.1.2.10"), 193 StaticRangeHighIP: net.ParseIP("10.1.2.200"), 194 }, { 195 // IPv4 VLAN subnet. 196 CIDR: "4.3.2.0/28", 197 Life: params.Dead, 198 ProviderId: "vlan-42", 199 SpaceTag: "space-space2", 200 Zones: []string{"zone1"}, 201 VLANTag: 42, 202 StaticRangeLowIP: net.ParseIP("4.3.2.2"), 203 StaticRangeHighIP: net.ParseIP("4.3.2.4"), 204 }} 205 spaces := []params.Space{{ 206 Name: "space1", 207 Subnets: append([]params.Subnet{}, subnets[:2]...), 208 }, { 209 Name: "space2", 210 Subnets: append([]params.Subnet{}, subnets[2:]...), 211 }} 212 return &StubAPI{ 213 Stub: &testing.Stub{}, 214 Spaces: spaces, 215 Subnets: subnets, 216 } 217 } 218 219 func (sa *StubAPI) Close() error { 220 sa.MethodCall(sa, "Close") 221 return sa.NextErr() 222 } 223 224 func (sa *StubAPI) ListSpaces() ([]params.Space, error) { 225 sa.MethodCall(sa, "ListSpaces") 226 if err := sa.NextErr(); err != nil { 227 return nil, err 228 } 229 return sa.Spaces, nil 230 } 231 232 func (sa *StubAPI) CreateSpace(name string, subnetIds []string, public bool) error { 233 sa.MethodCall(sa, "CreateSpace", name, subnetIds, public) 234 return sa.NextErr() 235 } 236 237 func (sa *StubAPI) RemoveSpace(name string) error { 238 sa.MethodCall(sa, "RemoveSpace", name) 239 return sa.NextErr() 240 } 241 242 func (sa *StubAPI) UpdateSpace(name string, subnetIds []string) error { 243 sa.MethodCall(sa, "UpdateSpace", name, subnetIds) 244 return sa.NextErr() 245 } 246 247 func (sa *StubAPI) RenameSpace(name, newName string) error { 248 sa.MethodCall(sa, "RenameSpace", name, newName) 249 return sa.NextErr() 250 }