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