github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/state/environ_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state_test 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 10 "github.com/juju/names" 11 jc "github.com/juju/testing/checkers" 12 "github.com/juju/utils" 13 gc "gopkg.in/check.v1" 14 15 "github.com/juju/juju/environs/config" 16 "github.com/juju/juju/state" 17 "github.com/juju/juju/testing" 18 "github.com/juju/juju/testing/factory" 19 ) 20 21 type EnvironSuite struct { 22 ConnSuite 23 } 24 25 var _ = gc.Suite(&EnvironSuite{}) 26 27 func (s *EnvironSuite) TestEnvironment(c *gc.C) { 28 env, err := s.State.Environment() 29 c.Assert(err, jc.ErrorIsNil) 30 31 expectedTag := names.NewEnvironTag(env.UUID()) 32 c.Assert(env.Tag(), gc.Equals, expectedTag) 33 c.Assert(env.ServerTag(), gc.Equals, expectedTag) 34 c.Assert(env.Name(), gc.Equals, "testenv") 35 c.Assert(env.Owner(), gc.Equals, s.Owner) 36 c.Assert(env.Life(), gc.Equals, state.Alive) 37 } 38 39 func (s *EnvironSuite) TestNewEnvironmentNonExistentLocalUser(c *gc.C) { 40 cfg, _ := s.createTestEnvConfig(c) 41 owner := names.NewUserTag("non-existent@local") 42 43 _, _, err := s.State.NewEnvironment(cfg, owner) 44 c.Assert(err, gc.ErrorMatches, `cannot create environment: user "non-existent" not found`) 45 } 46 47 func (s *EnvironSuite) TestNewEnvironmentSameUserSameNameFails(c *gc.C) { 48 cfg, _ := s.createTestEnvConfig(c) 49 owner := s.Factory.MakeUser(c, nil).UserTag() 50 51 // Create the first environment. 52 _, st1, err := s.State.NewEnvironment(cfg, owner) 53 c.Assert(err, jc.ErrorIsNil) 54 defer st1.Close() 55 56 // Attempt to create another environment with a different UUID but the 57 // same owner and name as the first. 58 newUUID, err := utils.NewUUID() 59 c.Assert(err, jc.ErrorIsNil) 60 cfg2 := testing.CustomEnvironConfig(c, testing.Attrs{ 61 "name": cfg.Name(), 62 "uuid": newUUID.String(), 63 }) 64 _, _, err = s.State.NewEnvironment(cfg2, owner) 65 errMsg := fmt.Sprintf("environment %q for %s already exists", cfg2.Name(), owner.Username()) 66 c.Assert(err, gc.ErrorMatches, errMsg) 67 c.Assert(errors.IsAlreadyExists(err), jc.IsTrue) 68 69 // Remove the first environment. 70 env1, err := st1.Environment() 71 c.Assert(err, jc.ErrorIsNil) 72 err = env1.Destroy() 73 c.Assert(err, jc.ErrorIsNil) 74 err = st1.RemoveAllEnvironDocs() 75 c.Assert(err, jc.ErrorIsNil) 76 77 // We should now be able to create the other environment. 78 env2, st2, err := s.State.NewEnvironment(cfg2, owner) 79 c.Assert(err, jc.ErrorIsNil) 80 defer st2.Close() 81 c.Assert(env2, gc.NotNil) 82 c.Assert(st2, gc.NotNil) 83 } 84 85 func (s *EnvironSuite) TestNewEnvironment(c *gc.C) { 86 cfg, uuid := s.createTestEnvConfig(c) 87 owner := names.NewUserTag("test@remote") 88 89 env, st, err := s.State.NewEnvironment(cfg, owner) 90 c.Assert(err, jc.ErrorIsNil) 91 defer st.Close() 92 93 envTag := names.NewEnvironTag(uuid) 94 assertEnvMatches := func(env *state.Environment) { 95 c.Assert(env.UUID(), gc.Equals, envTag.Id()) 96 c.Assert(env.Tag(), gc.Equals, envTag) 97 c.Assert(env.ServerTag(), gc.Equals, s.envTag) 98 c.Assert(env.Owner(), gc.Equals, owner) 99 c.Assert(env.Name(), gc.Equals, "testing") 100 c.Assert(env.Life(), gc.Equals, state.Alive) 101 } 102 assertEnvMatches(env) 103 104 // Since the environ tag for the State connection is different, 105 // asking for this environment through FindEntity returns a not found error. 106 env, err = s.State.GetEnvironment(envTag) 107 c.Assert(err, jc.ErrorIsNil) 108 assertEnvMatches(env) 109 110 env, err = st.Environment() 111 c.Assert(err, jc.ErrorIsNil) 112 assertEnvMatches(env) 113 114 _, err = s.State.FindEntity(envTag) 115 c.Assert(err, jc.Satisfies, errors.IsNotFound) 116 117 entity, err := st.FindEntity(envTag) 118 c.Assert(err, jc.ErrorIsNil) 119 c.Assert(entity.Tag(), gc.Equals, envTag) 120 121 // Ensure the environment is functional by adding a machine 122 _, err = st.AddMachine("quantal", state.JobHostUnits) 123 c.Assert(err, jc.ErrorIsNil) 124 } 125 126 func (s *EnvironSuite) TestStateServerEnvironment(c *gc.C) { 127 env, err := s.State.StateServerEnvironment() 128 c.Assert(err, jc.ErrorIsNil) 129 130 expectedTag := names.NewEnvironTag(env.UUID()) 131 c.Assert(env.Tag(), gc.Equals, expectedTag) 132 c.Assert(env.ServerTag(), gc.Equals, expectedTag) 133 c.Assert(env.Name(), gc.Equals, "testenv") 134 c.Assert(env.Owner(), gc.Equals, s.Owner) 135 c.Assert(env.Life(), gc.Equals, state.Alive) 136 } 137 138 func (s *EnvironSuite) TestStateServerEnvironmentAccessibleFromOtherEnvironments(c *gc.C) { 139 cfg, _ := s.createTestEnvConfig(c) 140 _, st, err := s.State.NewEnvironment(cfg, names.NewUserTag("test@remote")) 141 defer st.Close() 142 143 env, err := st.StateServerEnvironment() 144 c.Assert(err, jc.ErrorIsNil) 145 c.Assert(env.Tag(), gc.Equals, s.envTag) 146 c.Assert(env.Name(), gc.Equals, "testenv") 147 c.Assert(env.Owner(), gc.Equals, s.Owner) 148 c.Assert(env.Life(), gc.Equals, state.Alive) 149 } 150 151 func (s *EnvironSuite) TestConfigForStateServerEnv(c *gc.C) { 152 otherState := s.Factory.MakeEnvironment(c, &factory.EnvParams{Name: "other"}) 153 defer otherState.Close() 154 155 env, err := otherState.GetEnvironment(s.envTag) 156 c.Assert(err, jc.ErrorIsNil) 157 158 conf, err := env.Config() 159 c.Assert(err, jc.ErrorIsNil) 160 c.Assert(conf.Name(), gc.Equals, "testenv") 161 uuid, ok := conf.UUID() 162 c.Assert(ok, jc.IsTrue) 163 c.Assert(uuid, gc.Equals, s.envTag.Id()) 164 } 165 166 func (s *EnvironSuite) TestConfigForOtherEnv(c *gc.C) { 167 otherState := s.Factory.MakeEnvironment(c, &factory.EnvParams{Name: "other"}) 168 defer otherState.Close() 169 otherEnv, err := otherState.Environment() 170 c.Assert(err, jc.ErrorIsNil) 171 172 // By getting the environment through a different state connection, 173 // the underlying state pointer in the *state.Environment struct has 174 // a different environment tag. 175 env, err := s.State.GetEnvironment(otherEnv.EnvironTag()) 176 c.Assert(err, jc.ErrorIsNil) 177 178 conf, err := env.Config() 179 c.Assert(err, jc.ErrorIsNil) 180 c.Assert(conf.Name(), gc.Equals, "other") 181 uuid, ok := conf.UUID() 182 c.Assert(ok, jc.IsTrue) 183 c.Assert(uuid, gc.Equals, otherEnv.UUID()) 184 } 185 186 // createTestEnvConfig returns a new environment config and its UUID for testing. 187 func (s *EnvironSuite) createTestEnvConfig(c *gc.C) (*config.Config, string) { 188 uuid, err := utils.NewUUID() 189 c.Assert(err, jc.ErrorIsNil) 190 return testing.CustomEnvironConfig(c, testing.Attrs{ 191 "name": "testing", 192 "uuid": uuid.String(), 193 }), uuid.String() 194 } 195 196 func (s *EnvironSuite) TestEnvironmentConfigSameEnvAsState(c *gc.C) { 197 env, err := s.State.Environment() 198 c.Assert(err, jc.ErrorIsNil) 199 cfg, err := env.Config() 200 c.Assert(err, jc.ErrorIsNil) 201 uuid, exists := cfg.UUID() 202 c.Assert(exists, jc.IsTrue) 203 c.Assert(uuid, gc.Equals, s.State.EnvironUUID()) 204 } 205 206 func (s *EnvironSuite) TestEnvironmentConfigDifferentEnvThanState(c *gc.C) { 207 otherState := s.Factory.MakeEnvironment(c, nil) 208 defer otherState.Close() 209 env, err := otherState.Environment() 210 c.Assert(err, jc.ErrorIsNil) 211 cfg, err := env.Config() 212 c.Assert(err, jc.ErrorIsNil) 213 uuid, exists := cfg.UUID() 214 c.Assert(exists, jc.IsTrue) 215 c.Assert(uuid, gc.Equals, env.UUID()) 216 c.Assert(uuid, gc.Not(gc.Equals), s.State.EnvironUUID()) 217 } 218 219 func (s *EnvironSuite) TestDestroyStateServerEnvironment(c *gc.C) { 220 env, err := s.State.Environment() 221 c.Assert(err, jc.ErrorIsNil) 222 err = env.Destroy() 223 c.Assert(err, jc.ErrorIsNil) 224 } 225 226 func (s *EnvironSuite) TestDestroyOtherEnvironment(c *gc.C) { 227 st2 := s.Factory.MakeEnvironment(c, nil) 228 defer st2.Close() 229 env, err := st2.Environment() 230 c.Assert(err, jc.ErrorIsNil) 231 err = env.Destroy() 232 c.Assert(err, jc.ErrorIsNil) 233 } 234 235 func (s *EnvironSuite) TestDestroyStateServerEnvironmentFails(c *gc.C) { 236 st2 := s.Factory.MakeEnvironment(c, nil) 237 defer st2.Close() 238 env, err := s.State.Environment() 239 c.Assert(err, jc.ErrorIsNil) 240 c.Assert(env.Destroy(), gc.ErrorMatches, "failed to destroy environment: hosting 1 other environments") 241 } 242 243 func (s *EnvironSuite) TestDestroyStateServerEnvironmentRace(c *gc.C) { 244 // Simulate an environment being added just before the remove txn is 245 // called. 246 defer state.SetBeforeHooks(c, s.State, func() { 247 blocker := s.Factory.MakeEnvironment(c, nil) 248 err := blocker.Close() 249 c.Check(err, jc.ErrorIsNil) 250 }).Check() 251 252 env, err := s.State.Environment() 253 c.Assert(err, jc.ErrorIsNil) 254 c.Assert(env.Destroy(), gc.ErrorMatches, "failed to destroy environment: hosting 1 other environments") 255 } 256 257 func (s *EnvironSuite) TestDestroyStateServerAlreadyDyingRaceNoOp(c *gc.C) { 258 env, err := s.State.Environment() 259 c.Assert(err, jc.ErrorIsNil) 260 261 // Simulate an environment being destroyed by another client just before 262 // the remove txn is called. 263 defer state.SetBeforeHooks(c, s.State, func() { 264 c.Assert(env.Destroy(), jc.ErrorIsNil) 265 }).Check() 266 267 c.Assert(env.Destroy(), jc.ErrorIsNil) 268 } 269 270 func (s *EnvironSuite) TestDestroyStateServerAlreadyDyingNoOp(c *gc.C) { 271 env, err := s.State.Environment() 272 c.Assert(err, jc.ErrorIsNil) 273 274 c.Assert(env.Destroy(), jc.ErrorIsNil) 275 c.Assert(env.Destroy(), jc.ErrorIsNil) 276 } 277 278 func (s *EnvironSuite) TestListEnvironmentUsers(c *gc.C) { 279 env, err := s.State.Environment() 280 c.Assert(err, jc.ErrorIsNil) 281 282 expected := addEnvUsers(c, s.State) 283 obtained, err := env.Users() 284 c.Assert(err, gc.IsNil) 285 286 assertObtainedUsersMatchExpectedUsers(c, obtained, expected) 287 } 288 289 func (s *EnvironSuite) TestMisMatchedEnvs(c *gc.C) { 290 // create another environment 291 otherEnvState := s.Factory.MakeEnvironment(c, nil) 292 defer otherEnvState.Close() 293 otherEnv, err := otherEnvState.Environment() 294 c.Assert(err, jc.ErrorIsNil) 295 296 // get that environment from State 297 env, err := s.State.GetEnvironment(otherEnv.EnvironTag()) 298 c.Assert(err, jc.ErrorIsNil) 299 300 // check that the Users method errors 301 users, err := env.Users() 302 c.Assert(users, gc.IsNil) 303 c.Assert(err, gc.ErrorMatches, "cannot lookup environment users outside the current environment") 304 } 305 306 func (s *EnvironSuite) TestListUsersTwoEnvironments(c *gc.C) { 307 env, err := s.State.Environment() 308 c.Assert(err, jc.ErrorIsNil) 309 310 otherEnvState := s.Factory.MakeEnvironment(c, nil) 311 defer otherEnvState.Close() 312 otherEnv, err := otherEnvState.Environment() 313 c.Assert(err, jc.ErrorIsNil) 314 315 // Add users to both environments 316 expectedUsers := addEnvUsers(c, s.State) 317 expectedUsersOtherEnv := addEnvUsers(c, otherEnvState) 318 319 // test that only the expected users are listed for each environment 320 obtainedUsers, err := env.Users() 321 c.Assert(err, jc.ErrorIsNil) 322 assertObtainedUsersMatchExpectedUsers(c, obtainedUsers, expectedUsers) 323 324 obtainedUsersOtherEnv, err := otherEnv.Users() 325 c.Assert(err, jc.ErrorIsNil) 326 assertObtainedUsersMatchExpectedUsers(c, obtainedUsersOtherEnv, expectedUsersOtherEnv) 327 } 328 329 func addEnvUsers(c *gc.C, st *state.State) (expected []*state.EnvironmentUser) { 330 // get the environment owner 331 testAdmin := names.NewUserTag("test-admin") 332 owner, err := st.EnvironmentUser(testAdmin) 333 c.Assert(err, jc.ErrorIsNil) 334 335 f := factory.NewFactory(st) 336 return []*state.EnvironmentUser{ 337 // we expect the owner to be an existing environment user 338 owner, 339 // add new users to the environment 340 f.MakeEnvUser(c, nil), 341 f.MakeEnvUser(c, nil), 342 f.MakeEnvUser(c, nil), 343 } 344 } 345 346 func assertObtainedUsersMatchExpectedUsers(c *gc.C, obtainedUsers, expectedUsers []*state.EnvironmentUser) { 347 c.Assert(len(obtainedUsers), gc.Equals, len(expectedUsers)) 348 for i, obtained := range obtainedUsers { 349 c.Assert(obtained.EnvironmentTag().Id(), gc.Equals, expectedUsers[i].EnvironmentTag().Id()) 350 c.Assert(obtained.UserName(), gc.Equals, expectedUsers[i].UserName()) 351 c.Assert(obtained.DisplayName(), gc.Equals, expectedUsers[i].DisplayName()) 352 c.Assert(obtained.CreatedBy(), gc.Equals, expectedUsers[i].CreatedBy()) 353 } 354 } 355 356 func (s *EnvironSuite) TestAllEnvironments(c *gc.C) { 357 s.Factory.MakeEnvironment(c, &factory.EnvParams{ 358 Name: "test", Owner: names.NewUserTag("bob@remote")}).Close() 359 s.Factory.MakeEnvironment(c, &factory.EnvParams{ 360 Name: "test", Owner: names.NewUserTag("mary@remote")}).Close() 361 envs, err := s.State.AllEnvironments() 362 c.Assert(err, jc.ErrorIsNil) 363 c.Assert(envs, gc.HasLen, 3) 364 var obtained []string 365 for _, env := range envs { 366 obtained = append(obtained, fmt.Sprintf("%s/%s", env.Owner().Username(), env.Name())) 367 } 368 expected := []string{ 369 "test-admin@local/testenv", 370 "bob@remote/test", 371 "mary@remote/test", 372 } 373 c.Assert(obtained, jc.SameContents, expected) 374 } 375 376 func (s *EnvironSuite) TestHostedEnvironCount(c *gc.C) { 377 c.Assert(state.HostedEnvironCount(c, s.State), gc.Equals, 0) 378 379 st1 := s.Factory.MakeEnvironment(c, nil) 380 defer st1.Close() 381 c.Assert(state.HostedEnvironCount(c, s.State), gc.Equals, 1) 382 383 st2 := s.Factory.MakeEnvironment(c, nil) 384 defer st2.Close() 385 c.Assert(state.HostedEnvironCount(c, s.State), gc.Equals, 2) 386 387 env1, err := st1.Environment() 388 c.Assert(err, jc.ErrorIsNil) 389 c.Assert(env1.Destroy(), jc.ErrorIsNil) 390 c.Assert(state.HostedEnvironCount(c, s.State), gc.Equals, 1) 391 392 env2, err := st2.Environment() 393 c.Assert(err, jc.ErrorIsNil) 394 c.Assert(env2.Destroy(), jc.ErrorIsNil) 395 c.Assert(state.HostedEnvironCount(c, s.State), gc.Equals, 0) 396 }