github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/api/controller/legacy_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package controller_test 5 6 import ( 7 "fmt" 8 "net" 9 "time" 10 11 jc "github.com/juju/testing/checkers" 12 "github.com/juju/utils/clock" 13 gc "gopkg.in/check.v1" 14 "gopkg.in/juju/names.v2" 15 16 "github.com/juju/juju/api" 17 "github.com/juju/juju/api/base" 18 "github.com/juju/juju/api/controller" 19 "github.com/juju/juju/apiserver" 20 commontesting "github.com/juju/juju/apiserver/common/testing" 21 "github.com/juju/juju/apiserver/observer" 22 "github.com/juju/juju/apiserver/observer/fakeobserver" 23 "github.com/juju/juju/apiserver/params" 24 jujutesting "github.com/juju/juju/juju/testing" 25 "github.com/juju/juju/permission" 26 "github.com/juju/juju/state" 27 "github.com/juju/juju/state/multiwatcher" 28 "github.com/juju/juju/testing" 29 "github.com/juju/juju/testing/factory" 30 ) 31 32 // legacySuite has the tests for the controller client-side facade 33 // which use JujuConnSuite. The plan is to gradually move these tests 34 // to Suite in controller_test.go. 35 type legacySuite struct { 36 jujutesting.JujuConnSuite 37 commontesting.BlockHelper 38 } 39 40 var _ = gc.Suite(&legacySuite{}) 41 42 func (s *legacySuite) OpenAPI(c *gc.C) *controller.Client { 43 return controller.NewClient(s.OpenControllerAPI(c)) 44 } 45 46 func (s *legacySuite) TestAllModels(c *gc.C) { 47 owner := names.NewUserTag("user@remote") 48 s.Factory.MakeModel(c, &factory.ModelParams{ 49 Name: "first", Owner: owner}).Close() 50 s.Factory.MakeModel(c, &factory.ModelParams{ 51 Name: "second", Owner: owner}).Close() 52 53 sysManager := s.OpenAPI(c) 54 defer sysManager.Close() 55 envs, err := sysManager.AllModels() 56 c.Assert(err, jc.ErrorIsNil) 57 c.Assert(envs, gc.HasLen, 3) 58 59 var obtained []string 60 for _, env := range envs { 61 obtained = append(obtained, fmt.Sprintf("%s/%s", env.Owner, env.Name)) 62 } 63 expected := []string{ 64 "admin@local/controller", 65 "user@remote/first", 66 "user@remote/second", 67 } 68 c.Assert(obtained, jc.SameContents, expected) 69 } 70 71 func (s *legacySuite) TestModelConfig(c *gc.C) { 72 sysManager := s.OpenAPI(c) 73 defer sysManager.Close() 74 cfg, err := sysManager.ModelConfig() 75 c.Assert(err, jc.ErrorIsNil) 76 c.Assert(cfg["name"], gc.Equals, "controller") 77 } 78 79 func (s *legacySuite) TestControllerConfig(c *gc.C) { 80 sysManager := s.OpenAPI(c) 81 defer sysManager.Close() 82 cfg, err := sysManager.ControllerConfig() 83 c.Assert(err, jc.ErrorIsNil) 84 cfgFromDB, err := s.State.ControllerConfig() 85 c.Assert(err, jc.ErrorIsNil) 86 c.Assert(cfg["controller-uuid"], gc.Equals, cfgFromDB.ControllerUUID()) 87 c.Assert(int(cfg["state-port"].(float64)), gc.Equals, cfgFromDB.StatePort()) 88 c.Assert(int(cfg["api-port"].(float64)), gc.Equals, cfgFromDB.APIPort()) 89 } 90 91 func (s *legacySuite) TestDestroyController(c *gc.C) { 92 st := s.Factory.MakeModel(c, &factory.ModelParams{Name: "foo"}) 93 factory.NewFactory(st).MakeMachine(c, nil) // make it non-empty 94 st.Close() 95 96 sysManager := s.OpenAPI(c) 97 defer sysManager.Close() 98 err := sysManager.DestroyController(false) 99 c.Assert(err, gc.ErrorMatches, `failed to destroy model: hosting 1 other models \(controller has hosted models\)`) 100 } 101 102 func (s *legacySuite) TestListBlockedModels(c *gc.C) { 103 err := s.State.SwitchBlockOn(state.ChangeBlock, "change block for controller") 104 err = s.State.SwitchBlockOn(state.DestroyBlock, "destroy block for controller") 105 c.Assert(err, jc.ErrorIsNil) 106 107 sysManager := s.OpenAPI(c) 108 defer sysManager.Close() 109 results, err := sysManager.ListBlockedModels() 110 c.Assert(err, jc.ErrorIsNil) 111 c.Assert(results, jc.DeepEquals, []params.ModelBlockInfo{ 112 { 113 Name: "controller", 114 UUID: s.State.ModelUUID(), 115 OwnerTag: s.AdminUserTag(c).String(), 116 Blocks: []string{ 117 "BlockChange", 118 "BlockDestroy", 119 }, 120 }, 121 }) 122 } 123 124 func (s *legacySuite) TestRemoveBlocks(c *gc.C) { 125 s.State.SwitchBlockOn(state.DestroyBlock, "TestBlockDestroyModel") 126 s.State.SwitchBlockOn(state.ChangeBlock, "TestChangeBlock") 127 128 sysManager := s.OpenAPI(c) 129 defer sysManager.Close() 130 err := sysManager.RemoveBlocks() 131 c.Assert(err, jc.ErrorIsNil) 132 133 blocks, err := s.State.AllBlocksForController() 134 c.Assert(err, jc.ErrorIsNil) 135 c.Assert(blocks, gc.HasLen, 0) 136 } 137 138 func (s *legacySuite) TestWatchAllModels(c *gc.C) { 139 // The WatchAllModels infrastructure is comprehensively tested 140 // else. This test just ensure that the API calls work end-to-end. 141 sysManager := s.OpenAPI(c) 142 defer sysManager.Close() 143 144 w, err := sysManager.WatchAllModels() 145 c.Assert(err, jc.ErrorIsNil) 146 defer func() { 147 err := w.Stop() 148 c.Assert(err, jc.ErrorIsNil) 149 }() 150 151 deltasC := make(chan []multiwatcher.Delta) 152 go func() { 153 deltas, err := w.Next() 154 c.Assert(err, jc.ErrorIsNil) 155 deltasC <- deltas 156 }() 157 158 select { 159 case deltas := <-deltasC: 160 c.Assert(deltas, gc.HasLen, 1) 161 modelInfo := deltas[0].Entity.(*multiwatcher.ModelInfo) 162 163 env, err := s.State.Model() 164 c.Assert(err, jc.ErrorIsNil) 165 166 c.Assert(modelInfo.ModelUUID, gc.Equals, env.UUID()) 167 c.Assert(modelInfo.Name, gc.Equals, env.Name()) 168 c.Assert(modelInfo.Life, gc.Equals, multiwatcher.Life("alive")) 169 c.Assert(modelInfo.Owner, gc.Equals, env.Owner().Id()) 170 c.Assert(modelInfo.ControllerUUID, gc.Equals, env.ControllerUUID()) 171 case <-time.After(testing.LongWait): 172 c.Fatal("timed out") 173 } 174 } 175 176 func (s *legacySuite) TestAPIServerCanShutdownWithOutstandingNext(c *gc.C) { 177 178 lis, err := net.Listen("tcp", "localhost:0") 179 c.Assert(err, jc.ErrorIsNil) 180 181 srv, err := apiserver.NewServer(s.State, lis, apiserver.ServerConfig{ 182 Clock: clock.WallClock, 183 Cert: testing.ServerCert, 184 Key: testing.ServerKey, 185 Tag: names.NewMachineTag("0"), 186 DataDir: c.MkDir(), 187 LogDir: c.MkDir(), 188 NewObserver: func() observer.Observer { return &fakeobserver.Instance{} }, 189 AutocertURL: "https://0.1.2.3/no-autocert-here", 190 }) 191 c.Assert(err, gc.IsNil) 192 193 // Connect to the API server we've just started. 194 apiInfo := s.APIInfo(c) 195 apiInfo.Addrs = []string{lis.Addr().String()} 196 apiInfo.ModelTag = names.ModelTag{} 197 apiState, err := api.Open(apiInfo, api.DialOpts{}) 198 sysManager := controller.NewClient(apiState) 199 defer sysManager.Close() 200 201 w, err := sysManager.WatchAllModels() 202 c.Assert(err, jc.ErrorIsNil) 203 defer w.Stop() 204 205 deltasC := make(chan struct{}, 2) 206 go func() { 207 defer close(deltasC) 208 for { 209 _, err := w.Next() 210 if err != nil { 211 return 212 } 213 deltasC <- struct{}{} 214 } 215 }() 216 // Read the first event. 217 select { 218 case <-deltasC: 219 case <-time.After(testing.LongWait): 220 c.Fatal("timed out") 221 } 222 // Wait a little while for the Next call to actually arrive. 223 time.Sleep(testing.ShortWait) 224 225 // We should be able to close the server instance 226 // even when there's an outstanding Next call. 227 srvStopped := make(chan struct{}) 228 go func() { 229 srv.Stop() 230 close(srvStopped) 231 }() 232 233 select { 234 case <-srvStopped: 235 case <-time.After(testing.LongWait): 236 c.Fatal("timed out waiting for server to stop") 237 } 238 239 // Check that the Next call has returned too. 240 select { 241 case _, ok := <-deltasC: 242 if ok { 243 c.Fatalf("got unexpected event from deltasC") 244 } 245 case <-time.After(testing.LongWait): 246 c.Fatal("timed out") 247 } 248 } 249 250 func (s *legacySuite) TestModelStatus(c *gc.C) { 251 sysManager := s.OpenAPI(c) 252 defer sysManager.Close() 253 s.Factory.MakeMachine(c, nil) 254 modelTag := s.State.ModelTag() 255 results, err := sysManager.ModelStatus(modelTag) 256 c.Assert(err, jc.ErrorIsNil) 257 c.Assert(results, jc.DeepEquals, []base.ModelStatus{{ 258 UUID: modelTag.Id(), 259 TotalMachineCount: 1, 260 HostedMachineCount: 1, 261 ServiceCount: 0, 262 Owner: "admin@local", 263 Life: string(params.Alive), 264 Machines: []base.Machine{{Id: "0", InstanceId: "id-2", Status: "pending"}}, 265 }}) 266 } 267 268 func (s *legacySuite) TestGetControllerAccess(c *gc.C) { 269 controller := s.OpenAPI(c) 270 defer controller.Close() 271 err := controller.GrantController("fred@external", "addmodel") 272 c.Assert(err, jc.ErrorIsNil) 273 access, err := controller.GetControllerAccess("fred@external") 274 c.Assert(err, jc.ErrorIsNil) 275 c.Assert(access, gc.Equals, permission.Access("addmodel")) 276 }