github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/featuretests/cmd_juju_model_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package featuretests 5 6 import ( 7 "strings" 8 9 "github.com/juju/cmd" 10 "github.com/juju/errors" 11 "github.com/juju/loggo" 12 jc "github.com/juju/testing/checkers" 13 gc "gopkg.in/check.v1" 14 "gopkg.in/juju/names.v2" 15 "gopkg.in/yaml.v1" 16 17 "github.com/juju/juju/cmd/juju/commands" 18 "github.com/juju/juju/core/description" 19 "github.com/juju/juju/environs" 20 "github.com/juju/juju/environs/config" 21 "github.com/juju/juju/feature" 22 jujutesting "github.com/juju/juju/juju/testing" 23 "github.com/juju/juju/permission" 24 "github.com/juju/juju/state" 25 "github.com/juju/juju/testing" 26 "github.com/juju/juju/testing/factory" 27 ) 28 29 type cmdModelSuite struct { 30 jujutesting.RepoSuite 31 } 32 33 func (s *cmdModelSuite) SetUpTest(c *gc.C) { 34 s.RepoSuite.SetUpTest(c) 35 } 36 37 func (s *cmdModelSuite) run(c *gc.C, args ...string) *cmd.Context { 38 context := testing.Context(c) 39 jujuCmd := commands.NewJujuCommand(context) 40 err := testing.InitCommand(jujuCmd, args) 41 c.Assert(err, jc.ErrorIsNil) 42 err = jujuCmd.Run(context) 43 c.Assert(err, jc.ErrorIsNil) 44 return context 45 } 46 47 func (s *cmdModelSuite) TestGrantModelCmdStack(c *gc.C) { 48 username := "bar@ubuntuone" 49 context := s.run(c, "grant", username, "read", "controller") 50 obtained := strings.Replace(testing.Stdout(context), "\n", "", -1) 51 expected := "" 52 c.Assert(obtained, gc.Equals, expected) 53 54 user := names.NewUserTag(username) 55 modelUser, err := s.State.UserAccess(user, s.State.ModelTag()) 56 c.Assert(err, jc.ErrorIsNil) 57 c.Assert(modelUser.UserName, gc.Equals, user.Id()) 58 c.Assert(modelUser.CreatedBy.Id(), gc.Equals, s.AdminUserTag(c).Id()) 59 lastConn, err := s.State.LastModelConnection(modelUser.UserTag) 60 c.Assert(err, jc.Satisfies, state.IsNeverConnectedError) 61 c.Assert(lastConn.IsZero(), jc.IsTrue) 62 } 63 64 func (s *cmdModelSuite) TestRevokeModelCmdStack(c *gc.C) { 65 // Firstly share a model with a user 66 username := "bar@ubuntuone" 67 s.Factory.MakeModelUser(c, &factory.ModelUserParams{ 68 User: username, Access: permission.ReadAccess}) 69 70 // Because we are calling into juju through the main command, 71 // and the main command adds a warning logging writer, we need 72 // to clear the logging writers here. 73 loggo.RemoveWriter("warning") 74 75 // Then test that the unshare command stack is hooked up 76 context := s.run(c, "revoke", username, "read", "controller") 77 obtained := strings.Replace(testing.Stdout(context), "\n", "", -1) 78 expected := "" 79 c.Assert(obtained, gc.Equals, expected) 80 81 user := names.NewUserTag(username) 82 modelUser, err := s.State.UserAccess(user, s.State.ModelTag()) 83 c.Assert(errors.IsNotFound(err), jc.IsTrue) 84 c.Assert(modelUser, gc.DeepEquals, permission.UserAccess{}) 85 } 86 87 func (s *cmdModelSuite) TestModelUsersCmd(c *gc.C) { 88 // Firstly share an model with a user 89 username := "bar@ubuntuone" 90 context := s.run(c, "grant", username, "read", "controller") 91 user := names.NewUserTag(username) 92 modelUser, err := s.State.UserAccess(user, s.State.ModelTag()) 93 c.Assert(err, jc.ErrorIsNil) 94 c.Assert(modelUser, gc.NotNil) 95 96 // Because we are calling into juju through the main command, 97 // and the main command adds a warning logging writer, we need 98 // to clear the logging writers here. 99 loggo.RemoveWriter("warning") 100 101 context = s.run(c, "list-users", "controller") 102 c.Assert(err, jc.ErrorIsNil) 103 c.Assert(testing.Stdout(context), gc.Equals, ""+ 104 "Name Display name Access Last connection\n"+ 105 "admin* admin admin just now\n"+ 106 "bar@ubuntuone read never connected\n"+ 107 "\n") 108 109 } 110 111 func (s *cmdModelSuite) TestModelConfigGet(c *gc.C) { 112 err := s.State.UpdateModelConfig(map[string]interface{}{"special": "known"}, nil, nil) 113 c.Assert(err, jc.ErrorIsNil) 114 115 context := s.run(c, "model-config", "special") 116 c.Assert(testing.Stdout(context), gc.Equals, "known\n") 117 } 118 119 func (s *cmdModelSuite) TestModelConfigSet(c *gc.C) { 120 s.run(c, "model-config", "special=known") 121 s.assertModelValue(c, "special", "known") 122 } 123 124 func (s *cmdModelSuite) TestModelConfigReset(c *gc.C) { 125 err := s.State.UpdateModelConfig(map[string]interface{}{"special": "known"}, nil, nil) 126 c.Assert(err, jc.ErrorIsNil) 127 128 s.run(c, "model-config", "--reset", "special") 129 s.assertModelValueMissing(c, "special") 130 } 131 132 func (s *cmdModelSuite) TestModelDefaultsGet(c *gc.C) { 133 err := s.State.UpdateModelConfigDefaultValues(map[string]interface{}{"special": "known"}, nil, nil) 134 c.Assert(err, jc.ErrorIsNil) 135 136 context := s.run(c, "model-defaults", "special") 137 c.Assert(testing.Stdout(context), gc.Equals, ` 138 Attribute Default Controller 139 special - known 140 141 `[1:]) 142 } 143 144 func (s *cmdModelSuite) TestModelDefaultsGetRegion(c *gc.C) { 145 err := s.State.UpdateModelConfigDefaultValues(map[string]interface{}{"special": "known"}, nil, &environs.RegionSpec{"dummy", "dummy-region"}) 146 c.Assert(err, jc.ErrorIsNil) 147 148 context := s.run(c, "model-defaults", "dummy-region", "special") 149 c.Assert(testing.Stdout(context), gc.Equals, ` 150 Attribute Default Controller 151 special - - 152 dummy-region known - 153 154 `[1:]) 155 } 156 157 func (s *cmdModelSuite) TestModelDefaultsSet(c *gc.C) { 158 s.run(c, "model-defaults", "special=known") 159 defaults, err := s.State.ModelConfigDefaultValues() 160 c.Assert(err, jc.ErrorIsNil) 161 value, found := defaults["special"] 162 c.Assert(found, jc.IsTrue) 163 c.Assert(value.Controller, gc.Equals, "known") 164 } 165 166 func (s *cmdModelSuite) TestModelDefaultsSetRegion(c *gc.C) { 167 s.run(c, "model-defaults", "dummy/dummy-region", "special=known") 168 defaults, err := s.State.ModelConfigDefaultValues() 169 c.Assert(err, jc.ErrorIsNil) 170 value, found := defaults["special"] 171 c.Assert(found, jc.IsTrue) 172 c.Assert(value.Controller, gc.IsNil) 173 c.Assert(value.Regions, jc.SameContents, []config.RegionDefaultValue{{"dummy-region", "known"}}) 174 } 175 176 func (s *cmdModelSuite) TestModelDefaultsReset(c *gc.C) { 177 err := s.State.UpdateModelConfigDefaultValues(map[string]interface{}{"special": "known"}, nil, nil) 178 c.Assert(err, jc.ErrorIsNil) 179 180 s.run(c, "model-defaults", "--reset", "special") 181 defaults, err := s.State.ModelConfigDefaultValues() 182 c.Assert(err, jc.ErrorIsNil) 183 _, found := defaults["special"] 184 c.Assert(found, jc.IsFalse) 185 } 186 187 func (s *cmdModelSuite) TestModelDefaultsResetRegion(c *gc.C) { 188 err := s.State.UpdateModelConfigDefaultValues(map[string]interface{}{"special": "known"}, nil, &environs.RegionSpec{"dummy", "dummy-region"}) 189 c.Assert(err, jc.ErrorIsNil) 190 191 s.run(c, "model-defaults", "dummy-region", "--reset", "special") 192 defaults, err := s.State.ModelConfigDefaultValues() 193 c.Assert(err, jc.ErrorIsNil) 194 _, found := defaults["special"] 195 c.Assert(found, jc.IsFalse) 196 } 197 198 func (s *cmdModelSuite) TestRetryProvisioning(c *gc.C) { 199 s.Factory.MakeMachine(c, &factory.MachineParams{ 200 Jobs: []state.MachineJob{state.JobManageModel}, 201 }) 202 ctx := s.run(c, "retry-provisioning", "0") 203 output := testing.Stderr(ctx) 204 stripped := strings.Replace(output, "\n", "", -1) 205 c.Check(stripped, gc.Equals, `machine 0 is not in an error state`) 206 } 207 208 func (s *cmdModelSuite) TestDumpModel(c *gc.C) { 209 s.SetFeatureFlags(feature.DeveloperMode) 210 s.Factory.MakeMachine(c, &factory.MachineParams{ 211 Jobs: []state.MachineJob{state.JobManageModel}, 212 }) 213 ctx := s.run(c, "dump-model") 214 output := testing.Stdout(ctx) 215 // The output is yaml formatted output that is a model description. 216 model, err := description.Deserialize([]byte(output)) 217 c.Assert(err, jc.ErrorIsNil) 218 c.Assert(model.Config()["name"], gc.Equals, "controller") 219 } 220 221 func (s *cmdModelSuite) TestDumpModelDB(c *gc.C) { 222 s.SetFeatureFlags(feature.DeveloperMode) 223 s.Factory.MakeMachine(c, &factory.MachineParams{ 224 Jobs: []state.MachineJob{state.JobManageModel}, 225 }) 226 ctx := s.run(c, "dump-db") 227 output := testing.Stdout(ctx) 228 // The output is map of collection names to documents. 229 // Defaults to yaml output. 230 var valueMap map[string]interface{} 231 err := yaml.Unmarshal([]byte(output), &valueMap) 232 c.Assert(err, jc.ErrorIsNil) 233 c.Logf("%#v", valueMap) 234 model := valueMap["models"] 235 // yaml unmarshals maps with interface keys. 236 modelMap, ok := model.(map[interface{}]interface{}) 237 c.Assert(ok, jc.IsTrue) 238 c.Assert(modelMap["name"], gc.Equals, "controller") 239 } 240 241 func (s *cmdModelSuite) assertModelValue(c *gc.C, key string, expected interface{}) { 242 modelConfig, err := s.State.ModelConfig() 243 c.Assert(err, jc.ErrorIsNil) 244 value, found := modelConfig.AllAttrs()[key] 245 c.Assert(found, jc.IsTrue) 246 c.Assert(value, gc.Equals, expected) 247 } 248 249 func (s *cmdModelSuite) assertModelValueMissing(c *gc.C, key string) { 250 modelConfig, err := s.State.ModelConfig() 251 c.Assert(err, jc.ErrorIsNil) 252 _, found := modelConfig.AllAttrs()[key] 253 c.Assert(found, jc.IsFalse) 254 }