github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/commands/switch_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package commands 5 6 import ( 7 "errors" 8 "os" 9 10 "github.com/juju/cmd" 11 "github.com/juju/cmd/cmdtesting" 12 "github.com/juju/testing" 13 jc "github.com/juju/testing/checkers" 14 gc "gopkg.in/check.v1" 15 16 "github.com/juju/juju/cmd/modelcmd" 17 _ "github.com/juju/juju/juju" 18 "github.com/juju/juju/jujuclient" 19 "github.com/juju/juju/jujuclient/jujuclienttesting" 20 coretesting "github.com/juju/juju/testing" 21 ) 22 23 type SwitchSimpleSuite struct { 24 coretesting.FakeJujuXDGDataHomeSuite 25 testing.Stub 26 store *jujuclient.MemStore 27 stubStore *jujuclienttesting.StubStore 28 onRefresh func() 29 } 30 31 var _ = gc.Suite(&SwitchSimpleSuite{}) 32 33 func (s *SwitchSimpleSuite) SetUpTest(c *gc.C) { 34 s.FakeJujuXDGDataHomeSuite.SetUpTest(c) 35 s.Stub.ResetCalls() 36 s.store = jujuclient.NewMemStore() 37 s.stubStore = jujuclienttesting.WrapClientStore(s.store) 38 s.onRefresh = nil 39 } 40 41 func (s *SwitchSimpleSuite) refreshModels(store jujuclient.ClientStore, controllerName string) error { 42 s.MethodCall(s, "RefreshModels", store, controllerName) 43 if s.onRefresh != nil { 44 s.onRefresh() 45 } 46 return s.NextErr() 47 } 48 49 func (s *SwitchSimpleSuite) run(c *gc.C, args ...string) (*cmd.Context, error) { 50 cmd := &switchCommand{ 51 Store: s.stubStore, 52 RefreshModels: s.refreshModels, 53 } 54 return cmdtesting.RunCommand(c, modelcmd.WrapBase(cmd), args...) 55 } 56 57 func (s *SwitchSimpleSuite) TestNoArgs(c *gc.C) { 58 _, err := s.run(c) 59 c.Assert(err, gc.ErrorMatches, "no currently specified model") 60 } 61 62 func (s *SwitchSimpleSuite) TestNoArgsCurrentController(c *gc.C) { 63 s.addController(c, "a-controller") 64 s.store.CurrentControllerName = "a-controller" 65 ctx, err := s.run(c) 66 c.Assert(err, jc.ErrorIsNil) 67 c.Assert(cmdtesting.Stdout(ctx), gc.Equals, "a-controller\n") 68 } 69 70 func (s *SwitchSimpleSuite) TestUnknownControllerNameReturnsError(c *gc.C) { 71 s.addController(c, "a-controller") 72 s.store.CurrentControllerName = "a-controller" 73 _, err := s.run(c, "another-controller:modela") 74 c.Assert(err, gc.ErrorMatches, "controller another-controller not found") 75 } 76 77 func (s *SwitchSimpleSuite) TestNoArgsCurrentModel(c *gc.C) { 78 s.addController(c, "a-controller") 79 s.store.CurrentControllerName = "a-controller" 80 s.store.Models["a-controller"] = &jujuclient.ControllerModels{ 81 Models: map[string]jujuclient.ModelDetails{"admin/mymodel": {}}, 82 CurrentModel: "admin/mymodel", 83 } 84 ctx, err := s.run(c) 85 c.Assert(err, jc.ErrorIsNil) 86 c.Assert(cmdtesting.Stdout(ctx), gc.Equals, "a-controller:admin/mymodel\n") 87 } 88 89 func (s *SwitchSimpleSuite) TestSwitchWritesCurrentController(c *gc.C) { 90 s.addController(c, "a-controller") 91 context, err := s.run(c, "a-controller") 92 c.Assert(err, jc.ErrorIsNil) 93 c.Assert(cmdtesting.Stderr(context), gc.Equals, " -> a-controller (controller)\n") 94 s.stubStore.CheckCalls(c, []testing.StubCall{ 95 {"CurrentController", nil}, 96 {"ControllerByName", []interface{}{"a-controller"}}, 97 {"CurrentModel", []interface{}{"a-controller"}}, 98 {"SetCurrentController", []interface{}{"a-controller"}}, 99 }) 100 } 101 102 func (s *SwitchSimpleSuite) TestSwitchWithCurrentController(c *gc.C) { 103 s.store.CurrentControllerName = "old" 104 s.addController(c, "new") 105 context, err := s.run(c, "new") 106 c.Assert(err, jc.ErrorIsNil) 107 c.Assert(cmdtesting.Stderr(context), gc.Equals, "old (controller) -> new (controller)\n") 108 } 109 110 func (s *SwitchSimpleSuite) TestSwitchLocalControllerWithCurrent(c *gc.C) { 111 s.store.CurrentControllerName = "old" 112 s.addController(c, "new") 113 context, err := s.run(c, "new") 114 c.Assert(err, jc.ErrorIsNil) 115 c.Assert(cmdtesting.Stderr(context), gc.Equals, "old (controller) -> new (controller)\n") 116 } 117 118 func (s *SwitchSimpleSuite) TestSwitchLocalControllerWithCurrentExplicit(c *gc.C) { 119 s.store.CurrentControllerName = "old" 120 s.addController(c, "new") 121 context, err := s.run(c, "new:") 122 c.Assert(err, jc.ErrorIsNil) 123 c.Assert(cmdtesting.Stderr(context), gc.Equals, "old (controller) -> new (controller)\n") 124 } 125 126 func (s *SwitchSimpleSuite) TestSwitchSameController(c *gc.C) { 127 s.store.CurrentControllerName = "same" 128 s.addController(c, "same") 129 context, err := s.run(c, "same") 130 c.Assert(err, jc.ErrorIsNil) 131 c.Assert(cmdtesting.Stderr(context), gc.Equals, "same (controller) (no change)\n") 132 s.stubStore.CheckCalls(c, []testing.StubCall{ 133 {"CurrentController", nil}, 134 {"CurrentModel", []interface{}{"same"}}, 135 {"ControllerByName", []interface{}{"same"}}, 136 }) 137 } 138 139 func (s *SwitchSimpleSuite) TestSwitchControllerToModel(c *gc.C) { 140 s.store.CurrentControllerName = "ctrl" 141 s.addController(c, "ctrl") 142 s.store.Models["ctrl"] = &jujuclient.ControllerModels{ 143 Models: map[string]jujuclient.ModelDetails{"admin/mymodel": {}}, 144 } 145 context, err := s.run(c, "mymodel") 146 c.Assert(err, jc.ErrorIsNil) 147 c.Assert(cmdtesting.Stderr(context), gc.Equals, "ctrl (controller) -> ctrl:admin/mymodel\n") 148 s.stubStore.CheckCalls(c, []testing.StubCall{ 149 {"CurrentController", nil}, 150 {"CurrentModel", []interface{}{"ctrl"}}, 151 {"ControllerByName", []interface{}{"mymodel"}}, 152 {"AccountDetails", []interface{}{"ctrl"}}, 153 {"SetCurrentModel", []interface{}{"ctrl", "admin/mymodel"}}, 154 }) 155 c.Assert(s.store.Models["ctrl"].CurrentModel, gc.Equals, "admin/mymodel") 156 } 157 158 func (s *SwitchSimpleSuite) TestSwitchControllerToModelDifferentController(c *gc.C) { 159 s.store.CurrentControllerName = "old" 160 s.addController(c, "new") 161 s.store.Models["new"] = &jujuclient.ControllerModels{ 162 Models: map[string]jujuclient.ModelDetails{"admin/mymodel": {}}, 163 } 164 context, err := s.run(c, "new:mymodel") 165 c.Assert(err, jc.ErrorIsNil) 166 c.Assert(cmdtesting.Stderr(context), gc.Equals, "old (controller) -> new:admin/mymodel\n") 167 s.stubStore.CheckCalls(c, []testing.StubCall{ 168 {"CurrentController", nil}, 169 {"CurrentModel", []interface{}{"old"}}, 170 {"ControllerByName", []interface{}{"new:mymodel"}}, 171 {"ControllerByName", []interface{}{"new"}}, 172 {"AccountDetails", []interface{}{"new"}}, 173 {"SetCurrentModel", []interface{}{"new", "admin/mymodel"}}, 174 {"SetCurrentController", []interface{}{"new"}}, 175 }) 176 c.Assert(s.store.Models["new"].CurrentModel, gc.Equals, "admin/mymodel") 177 } 178 179 func (s *SwitchSimpleSuite) TestSwitchControllerSameNameAsModel(c *gc.C) { 180 s.store.CurrentControllerName = "old" 181 s.addController(c, "new") 182 s.addController(c, "old") 183 s.store.Models["new"] = &jujuclient.ControllerModels{ 184 Models: map[string]jujuclient.ModelDetails{"admin/mymodel": {}, "admin/old": {}}, 185 } 186 s.store.Models["old"] = &jujuclient.ControllerModels{ 187 Models: map[string]jujuclient.ModelDetails{"admin/somemodel": {}}, 188 } 189 _, err := s.run(c, "new:mymodel") 190 c.Assert(err, jc.ErrorIsNil) 191 context, err := s.run(c, "old") 192 c.Assert(cmdtesting.Stderr(context), gc.Equals, "new:admin/mymodel -> old (controller)\n") 193 } 194 195 func (s *SwitchSimpleSuite) TestSwitchControllerSameNameAsModelExplicitModel(c *gc.C) { 196 s.store.CurrentControllerName = "old" 197 s.addController(c, "new") 198 s.addController(c, "old") 199 s.store.Models["new"] = &jujuclient.ControllerModels{ 200 Models: map[string]jujuclient.ModelDetails{"admin/mymodel": {}, "admin/old": {}}, 201 } 202 s.store.Models["old"] = &jujuclient.ControllerModels{ 203 Models: map[string]jujuclient.ModelDetails{"admin/somemodel": {}}, 204 } 205 _, err := s.run(c, "new:mymodel") 206 c.Assert(err, jc.ErrorIsNil) 207 context, err := s.run(c, ":old") 208 c.Assert(cmdtesting.Stderr(context), gc.Equals, "new:admin/mymodel -> new:admin/old\n") 209 } 210 211 func (s *SwitchSimpleSuite) TestSwitchLocalControllerToModelDifferentController(c *gc.C) { 212 s.store.CurrentControllerName = "old" 213 s.addController(c, "new") 214 s.store.Models["new"] = &jujuclient.ControllerModels{ 215 Models: map[string]jujuclient.ModelDetails{"admin/mymodel": {}}, 216 } 217 context, err := s.run(c, "new:mymodel") 218 c.Assert(err, jc.ErrorIsNil) 219 c.Assert(cmdtesting.Stderr(context), gc.Equals, "old (controller) -> new:admin/mymodel\n") 220 s.stubStore.CheckCalls(c, []testing.StubCall{ 221 {"CurrentController", nil}, 222 {"CurrentModel", []interface{}{"old"}}, 223 {"ControllerByName", []interface{}{"new:mymodel"}}, 224 {"ControllerByName", []interface{}{"new"}}, 225 {"AccountDetails", []interface{}{"new"}}, 226 {"SetCurrentModel", []interface{}{"new", "admin/mymodel"}}, 227 {"SetCurrentController", []interface{}{"new"}}, 228 }) 229 c.Assert(s.store.Models["new"].CurrentModel, gc.Equals, "admin/mymodel") 230 } 231 232 func (s *SwitchSimpleSuite) TestSwitchControllerToDifferentControllerCurrentModel(c *gc.C) { 233 s.store.CurrentControllerName = "old" 234 s.addController(c, "new") 235 s.store.Models["new"] = &jujuclient.ControllerModels{ 236 Models: map[string]jujuclient.ModelDetails{"admin/mymodel": {}}, 237 CurrentModel: "admin/mymodel", 238 } 239 context, err := s.run(c, "new:mymodel") 240 c.Assert(err, jc.ErrorIsNil) 241 c.Assert(cmdtesting.Stderr(context), gc.Equals, "old (controller) -> new:admin/mymodel\n") 242 s.stubStore.CheckCalls(c, []testing.StubCall{ 243 {"CurrentController", nil}, 244 {"CurrentModel", []interface{}{"old"}}, 245 {"ControllerByName", []interface{}{"new:mymodel"}}, 246 {"ControllerByName", []interface{}{"new"}}, 247 {"AccountDetails", []interface{}{"new"}}, 248 {"SetCurrentModel", []interface{}{"new", "admin/mymodel"}}, 249 {"SetCurrentController", []interface{}{"new"}}, 250 }) 251 } 252 253 func (s *SwitchSimpleSuite) TestSwitchToModelDifferentOwner(c *gc.C) { 254 s.store.CurrentControllerName = "same" 255 s.addController(c, "same") 256 s.store.Models["same"] = &jujuclient.ControllerModels{ 257 Models: map[string]jujuclient.ModelDetails{ 258 "admin/mymodel": {}, 259 "bianca/mymodel": {}, 260 }, 261 CurrentModel: "admin/mymodel", 262 } 263 context, err := s.run(c, "bianca/mymodel") 264 c.Assert(err, jc.ErrorIsNil) 265 c.Assert(cmdtesting.Stderr(context), gc.Equals, "same:admin/mymodel -> same:bianca/mymodel\n") 266 c.Assert(s.store.Models["same"].CurrentModel, gc.Equals, "bianca/mymodel") 267 } 268 269 func (s *SwitchSimpleSuite) TestSwitchUnknownNoCurrentController(c *gc.C) { 270 _, err := s.run(c, "unknown") 271 c.Assert(err, gc.ErrorMatches, `"unknown" is not the name of a model or controller`) 272 s.stubStore.CheckCalls(c, []testing.StubCall{ 273 {"CurrentController", nil}, 274 {"ControllerByName", []interface{}{"unknown"}}, 275 }) 276 } 277 278 func (s *SwitchSimpleSuite) TestSwitchUnknownCurrentControllerRefreshModels(c *gc.C) { 279 s.store.CurrentControllerName = "ctrl" 280 s.addController(c, "ctrl") 281 s.onRefresh = func() { 282 s.store.Models["ctrl"] = &jujuclient.ControllerModels{ 283 Models: map[string]jujuclient.ModelDetails{"admin/unknown": {}}, 284 } 285 } 286 ctx, err := s.run(c, "unknown") 287 c.Assert(err, jc.ErrorIsNil) 288 c.Assert(cmdtesting.Stderr(ctx), gc.Equals, "ctrl (controller) -> ctrl:admin/unknown\n") 289 s.CheckCallNames(c, "RefreshModels") 290 } 291 292 func (s *SwitchSimpleSuite) TestSwitchUnknownCurrentControllerRefreshModelsStillUnknown(c *gc.C) { 293 s.store.CurrentControllerName = "ctrl" 294 s.addController(c, "ctrl") 295 _, err := s.run(c, "unknown") 296 c.Assert(err, gc.ErrorMatches, `"unknown" is not the name of a model or controller`) 297 s.CheckCallNames(c, "RefreshModels") 298 } 299 300 func (s *SwitchSimpleSuite) TestSwitchUnknownCurrentControllerRefreshModelsFails(c *gc.C) { 301 s.store.CurrentControllerName = "ctrl" 302 s.addController(c, "ctrl") 303 s.SetErrors(errors.New("not very refreshing")) 304 _, err := s.run(c, "unknown") 305 c.Assert(err, gc.ErrorMatches, "refreshing models cache: not very refreshing") 306 s.CheckCallNames(c, "RefreshModels") 307 } 308 309 func (s *SwitchSimpleSuite) TestSettingWhenModelEnvVarSet(c *gc.C) { 310 os.Setenv("JUJU_MODEL", "using-model") 311 _, err := s.run(c, "erewhemos-2") 312 c.Assert(err, gc.ErrorMatches, `cannot switch when JUJU_MODEL is overriding the model \(set to "using-model"\)`) 313 } 314 315 func (s *SwitchSimpleSuite) TestSettingWhenControllerEnvVarSet(c *gc.C) { 316 os.Setenv("JUJU_CONTROLLER", "using-controller") 317 _, err := s.run(c, "erewhemos-2") 318 c.Assert(err, gc.ErrorMatches, `cannot switch when JUJU_CONTROLLER is overriding the controller \(set to "using-controller"\)`) 319 } 320 321 func (s *SwitchSimpleSuite) TestTooManyParams(c *gc.C) { 322 _, err := s.run(c, "foo", "bar") 323 c.Assert(err, gc.ErrorMatches, `unrecognized args: ."bar".`) 324 } 325 326 func (s *SwitchSimpleSuite) addController(c *gc.C, name string) { 327 s.store.Controllers[name] = jujuclient.ControllerDetails{} 328 s.store.Accounts[name] = jujuclient.AccountDetails{ 329 User: "admin", 330 } 331 } 332 333 func (s *SwitchSimpleSuite) TestSwitchCurrentModelInStore(c *gc.C) { 334 s.store.CurrentControllerName = "same" 335 s.addController(c, "same") 336 s.store.Models["same"] = &jujuclient.ControllerModels{ 337 Models: map[string]jujuclient.ModelDetails{ 338 "admin/mymodel": {}, 339 }, 340 CurrentModel: "admin/mymodel", 341 } 342 context, err := s.run(c, "mymodel") 343 c.Assert(err, jc.ErrorIsNil) 344 c.Assert(cmdtesting.Stderr(context), gc.Equals, "same:admin/mymodel (no change)\n") 345 s.stubStore.CheckCalls(c, []testing.StubCall{ 346 {"CurrentController", nil}, 347 {"CurrentModel", []interface{}{"same"}}, 348 {"ControllerByName", []interface{}{"mymodel"}}, 349 {"AccountDetails", []interface{}{"same"}}, 350 {"SetCurrentModel", []interface{}{"same", "admin/mymodel"}}, 351 }) 352 } 353 354 func (s *SwitchSimpleSuite) TestSwitchCurrentModelNoLongerInStore(c *gc.C) { 355 s.store.CurrentControllerName = "same" 356 s.addController(c, "same") 357 s.store.Models["same"] = &jujuclient.ControllerModels{CurrentModel: "admin/mymodel"} 358 _, err := s.run(c, "mymodel") 359 c.Assert(err, gc.ErrorMatches, `"mymodel" is not the name of a model or controller`) 360 }