github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/modelcmd/modelcommand_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package modelcmd_test 5 6 import ( 7 "fmt" 8 "os" 9 10 "github.com/juju/cmd" 11 "github.com/juju/cmd/cmdtesting" 12 "github.com/juju/names" 13 jc "github.com/juju/testing/checkers" 14 gc "gopkg.in/check.v1" 15 16 apitesting "github.com/juju/juju/api/testing" 17 "github.com/juju/juju/cmd/modelcmd" 18 "github.com/juju/juju/juju/osenv" 19 "github.com/juju/juju/jujuclient" 20 "github.com/juju/juju/jujuclient/jujuclienttesting" 21 "github.com/juju/juju/testing" 22 ) 23 24 type ModelCommandSuite struct { 25 testing.FakeJujuXDGDataHomeSuite 26 store *jujuclienttesting.MemStore 27 } 28 29 func (s *ModelCommandSuite) SetUpTest(c *gc.C) { 30 s.FakeJujuXDGDataHomeSuite.SetUpTest(c) 31 s.PatchEnvironment("JUJU_CLI_VERSION", "") 32 33 err := modelcmd.WriteCurrentController("foo") 34 c.Assert(err, jc.ErrorIsNil) 35 36 s.store = jujuclienttesting.NewMemStore() 37 s.store.Accounts["foo"] = &jujuclient.ControllerAccounts{ 38 Accounts: map[string]jujuclient.AccountDetails{ 39 "bar@baz": {User: "b@r", Password: "hunter2"}, 40 }, 41 CurrentAccount: "bar@baz", 42 } 43 } 44 45 var _ = gc.Suite(&ModelCommandSuite{}) 46 47 func (s *ModelCommandSuite) TestGetCurrentModelNothingSet(c *gc.C) { 48 err := modelcmd.WriteCurrentController("") 49 c.Assert(err, jc.ErrorIsNil) 50 env, err := modelcmd.GetCurrentModel(s.store) 51 c.Assert(env, gc.Equals, "") 52 c.Assert(err, jc.ErrorIsNil) 53 } 54 55 func (s *ModelCommandSuite) TestGetCurrentModelCurrentControllerNoCurrentAccount(c *gc.C) { 56 delete(s.store.Accounts, "foo") 57 env, err := modelcmd.GetCurrentModel(s.store) 58 c.Assert(env, gc.Equals, "") 59 c.Assert(err, jc.ErrorIsNil) 60 } 61 62 func (s *ModelCommandSuite) TestGetCurrentModelCurrentControllerNoCurrentModel(c *gc.C) { 63 env, err := modelcmd.GetCurrentModel(s.store) 64 c.Assert(env, gc.Equals, "") 65 c.Assert(err, jc.ErrorIsNil) 66 } 67 68 func (s *ModelCommandSuite) TestGetCurrentModelCurrentControllerAccountModel(c *gc.C) { 69 err := s.store.UpdateModel("foo", "bar@baz", "mymodel", jujuclient.ModelDetails{"uuid"}) 70 c.Assert(err, jc.ErrorIsNil) 71 err = s.store.SetCurrentModel("foo", "bar@baz", "mymodel") 72 c.Assert(err, jc.ErrorIsNil) 73 74 env, err := modelcmd.GetCurrentModel(s.store) 75 c.Assert(err, jc.ErrorIsNil) 76 c.Assert(env, gc.Equals, "mymodel") 77 } 78 79 func (s *ModelCommandSuite) TestGetCurrentModelJujuEnvSet(c *gc.C) { 80 os.Setenv(osenv.JujuModelEnvKey, "magic") 81 env, err := modelcmd.GetCurrentModel(s.store) 82 c.Assert(env, gc.Equals, "magic") 83 c.Assert(err, jc.ErrorIsNil) 84 } 85 86 func (s *ModelCommandSuite) TestGetCurrentModelBothSet(c *gc.C) { 87 os.Setenv(osenv.JujuModelEnvKey, "magic") 88 89 err := s.store.UpdateModel("foo", "bar@baz", "mymodel", jujuclient.ModelDetails{"uuid"}) 90 c.Assert(err, jc.ErrorIsNil) 91 err = s.store.SetCurrentModel("foo", "bar@baz", "mymodel") 92 c.Assert(err, jc.ErrorIsNil) 93 94 env, err := modelcmd.GetCurrentModel(s.store) 95 c.Assert(err, jc.ErrorIsNil) 96 c.Assert(env, gc.Equals, "magic") 97 } 98 99 func (s *ModelCommandSuite) TestModelCommandInitExplicit(c *gc.C) { 100 // Take model name from command line arg. 101 s.testEnsureModelName(c, "explicit", "-m", "explicit") 102 } 103 104 func (s *ModelCommandSuite) TestModelCommandInitExplicitLongForm(c *gc.C) { 105 // Take model name from command line arg. 106 s.testEnsureModelName(c, "explicit", "--model", "explicit") 107 } 108 109 func (s *ModelCommandSuite) TestModelCommandInitEnvFile(c *gc.C) { 110 err := s.store.UpdateModel("foo", "bar@baz", "mymodel", jujuclient.ModelDetails{"uuid"}) 111 c.Assert(err, jc.ErrorIsNil) 112 err = s.store.SetCurrentModel("foo", "bar@baz", "mymodel") 113 c.Assert(err, jc.ErrorIsNil) 114 s.testEnsureModelName(c, "mymodel") 115 } 116 117 func (s *ModelCommandSuite) TestBootstrapContext(c *gc.C) { 118 ctx := modelcmd.BootstrapContext(&cmd.Context{}) 119 c.Assert(ctx.ShouldVerifyCredentials(), jc.IsTrue) 120 } 121 122 func (s *ModelCommandSuite) TestBootstrapContextNoVerify(c *gc.C) { 123 ctx := modelcmd.BootstrapContextNoVerify(&cmd.Context{}) 124 c.Assert(ctx.ShouldVerifyCredentials(), jc.IsFalse) 125 } 126 127 func (s *ModelCommandSuite) TestWrapWithoutFlags(c *gc.C) { 128 cmd := new(testCommand) 129 wrapped := modelcmd.Wrap(cmd, modelcmd.ModelSkipFlags) 130 args := []string{"-m", "testenv"} 131 err := cmdtesting.InitCommand(wrapped, args) 132 // 1st position is always the flag 133 msg := fmt.Sprintf("flag provided but not defined: %v", args[0]) 134 c.Assert(err, gc.ErrorMatches, msg) 135 } 136 137 func (*ModelCommandSuite) TestSplitModelName(c *gc.C) { 138 assert := func(in, controller, model string) { 139 outController, outModel := modelcmd.SplitModelName(in) 140 c.Assert(outController, gc.Equals, controller) 141 c.Assert(outModel, gc.Equals, model) 142 } 143 assert("model", "", "model") 144 assert("ctrl:model", "ctrl", "model") 145 assert("ctrl:", "ctrl", "") 146 assert(":model", "", "model") 147 } 148 149 func (*ModelCommandSuite) TestJoinModelName(c *gc.C) { 150 assert := func(controller, model, expect string) { 151 out := modelcmd.JoinModelName(controller, model) 152 c.Assert(out, gc.Equals, expect) 153 } 154 assert("ctrl", "", "ctrl:") 155 assert("", "model", ":model") 156 assert("ctrl", "model", "ctrl:model") 157 } 158 159 func (s *ModelCommandSuite) testEnsureModelName(c *gc.C, expect string, args ...string) { 160 cmd, err := initTestCommand(c, s.store, args...) 161 c.Assert(err, jc.ErrorIsNil) 162 c.Assert(cmd.ConnectionName(), gc.Equals, expect) 163 } 164 165 type testCommand struct { 166 modelcmd.ModelCommandBase 167 } 168 169 func (c *testCommand) Info() *cmd.Info { 170 panic("should not be called") 171 } 172 173 func (c *testCommand) Run(ctx *cmd.Context) error { 174 panic("should not be called") 175 } 176 177 func initTestCommand(c *gc.C, store jujuclient.ClientStore, args ...string) (*testCommand, error) { 178 cmd := new(testCommand) 179 cmd.SetClientStore(store) 180 wrapped := modelcmd.Wrap(cmd) 181 return cmd, cmdtesting.InitCommand(wrapped, args) 182 } 183 184 type closer struct{} 185 186 func (*closer) Close() error { 187 return nil 188 } 189 190 var _ = gc.Suite(&macaroonLoginSuite{}) 191 192 type macaroonLoginSuite struct { 193 apitesting.MacaroonSuite 194 store *jujuclienttesting.MemStore 195 controllerName string 196 accountName string 197 modelName string 198 } 199 200 const testUser = "testuser@somewhere" 201 202 func (s *macaroonLoginSuite) SetUpTest(c *gc.C) { 203 s.MacaroonSuite.SetUpTest(c) 204 s.MacaroonSuite.AddModelUser(c, testUser) 205 206 s.controllerName = "my-controller" 207 s.accountName = "my@account" 208 s.modelName = "my-model" 209 modelTag := names.NewModelTag(s.State.ModelUUID()) 210 apiInfo := s.APIInfo(c) 211 212 s.store = jujuclienttesting.NewMemStore() 213 s.store.Controllers[s.controllerName] = jujuclient.ControllerDetails{ 214 APIEndpoints: apiInfo.Addrs, 215 ControllerUUID: apiInfo.ModelTag.Id(), 216 CACert: apiInfo.CACert, 217 } 218 s.store.Accounts[s.controllerName] = &jujuclient.ControllerAccounts{ 219 Accounts: map[string]jujuclient.AccountDetails{ 220 // Empty password forces use of macaroons. 221 s.accountName: {User: s.accountName}, 222 }, 223 CurrentAccount: s.accountName, 224 } 225 s.store.Models[s.controllerName] = jujuclient.ControllerAccountModels{ 226 AccountModels: map[string]*jujuclient.AccountModels{ 227 s.accountName: { 228 Models: map[string]jujuclient.ModelDetails{ 229 s.modelName: {modelTag.Id()}, 230 }, 231 }, 232 }, 233 } 234 } 235 236 func (s *macaroonLoginSuite) TestsSuccessfulLogin(c *gc.C) { 237 s.DischargerLogin = func() string { 238 return testUser 239 } 240 241 cmd := modelcmd.NewModelCommandBase(s.store, s.controllerName, s.accountName, s.modelName) 242 _, err := cmd.NewAPIRoot() 243 c.Assert(err, jc.ErrorIsNil) 244 } 245 246 func (s *macaroonLoginSuite) TestsFailToObtainDischargeLogin(c *gc.C) { 247 s.DischargerLogin = func() string { 248 return "" 249 } 250 251 cmd := modelcmd.NewModelCommandBase(s.store, s.controllerName, s.accountName, s.modelName) 252 _, err := cmd.NewAPIRoot() 253 c.Assert(err, gc.ErrorMatches, "connecting with cached addresses: cannot get discharge.*") 254 } 255 256 func (s *macaroonLoginSuite) TestsUnknownUserLogin(c *gc.C) { 257 s.DischargerLogin = func() string { 258 return "testUnknown@nowhere" 259 } 260 261 cmd := modelcmd.NewModelCommandBase(s.store, s.controllerName, s.accountName, s.modelName) 262 _, err := cmd.NewAPIRoot() 263 c.Assert(err, gc.ErrorMatches, "connecting with cached addresses: invalid entity name or password \\(unauthorized access\\)") 264 }