github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/apiserver/migrationtarget/migrationtarget_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package migrationtarget_test 5 6 import ( 7 "github.com/juju/errors" 8 jc "github.com/juju/testing/checkers" 9 "github.com/juju/utils" 10 "github.com/juju/version" 11 gc "gopkg.in/check.v1" 12 "gopkg.in/juju/names.v2" 13 14 "github.com/juju/juju/apiserver/common" 15 "github.com/juju/juju/apiserver/facade/facadetest" 16 "github.com/juju/juju/apiserver/migrationtarget" 17 "github.com/juju/juju/apiserver/params" 18 apiservertesting "github.com/juju/juju/apiserver/testing" 19 "github.com/juju/juju/core/description" 20 "github.com/juju/juju/provider/dummy" 21 "github.com/juju/juju/state" 22 statetesting "github.com/juju/juju/state/testing" 23 "github.com/juju/juju/testing" 24 ) 25 26 type Suite struct { 27 statetesting.StateSuite 28 resources *common.Resources 29 authorizer apiservertesting.FakeAuthorizer 30 } 31 32 var _ = gc.Suite(&Suite{}) 33 34 func (s *Suite) SetUpTest(c *gc.C) { 35 // Set up InitialConfig with a dummy provider configuration. This 36 // is required to allow model import test to work. 37 s.InitialConfig = testing.CustomModelConfig(c, dummy.SampleConfig()) 38 39 // The call up to StateSuite's SetUpTest uses s.InitialConfig so 40 // it has to happen here. 41 s.StateSuite.SetUpTest(c) 42 43 s.resources = common.NewResources() 44 s.AddCleanup(func(*gc.C) { s.resources.StopAll() }) 45 46 s.authorizer = apiservertesting.FakeAuthorizer{ 47 Tag: s.Owner, 48 AdminTag: s.Owner, 49 } 50 } 51 52 func (s *Suite) TestFacadeRegistered(c *gc.C) { 53 factory, err := common.Facades.GetFactory("MigrationTarget", 1) 54 c.Assert(err, jc.ErrorIsNil) 55 56 api, err := factory(facadetest.Context{ 57 State_: s.State, 58 Resources_: s.resources, 59 Auth_: s.authorizer, 60 }) 61 c.Assert(err, jc.ErrorIsNil) 62 c.Assert(api, gc.FitsTypeOf, new(migrationtarget.API)) 63 } 64 65 func (s *Suite) TestNotUser(c *gc.C) { 66 s.authorizer.Tag = names.NewMachineTag("0") 67 _, err := s.newAPI() 68 c.Assert(errors.Cause(err), gc.Equals, common.ErrPerm) 69 } 70 71 func (s *Suite) TestNotControllerAdmin(c *gc.C) { 72 s.authorizer.Tag = names.NewUserTag("jrandomuser") 73 _, err := s.newAPI() 74 c.Assert(errors.Cause(err), gc.Equals, common.ErrPerm) 75 } 76 77 func (s *Suite) importModel(c *gc.C, api *migrationtarget.API) names.ModelTag { 78 uuid, bytes := s.makeExportedModel(c) 79 err := api.Import(params.SerializedModel{Bytes: bytes}) 80 c.Assert(err, jc.ErrorIsNil) 81 return names.NewModelTag(uuid) 82 } 83 84 func (s *Suite) TestPrechecks(c *gc.C) { 85 api := s.mustNewAPI(c) 86 args := params.MigrationModelInfo{ 87 UUID: "uuid", 88 Name: "some-model", 89 OwnerTag: names.NewUserTag("someone").String(), 90 AgentVersion: s.controllerVersion(c), 91 } 92 err := api.Prechecks(args) 93 c.Assert(err, jc.ErrorIsNil) 94 } 95 96 func (s *Suite) TestPrechecksFail(c *gc.C) { 97 controllerVersion := s.controllerVersion(c) 98 99 // Set the model version ahead of the controller. 100 modelVersion := controllerVersion 101 modelVersion.Minor++ 102 103 api := s.mustNewAPI(c) 104 args := params.MigrationModelInfo{ 105 AgentVersion: modelVersion, 106 } 107 err := api.Prechecks(args) 108 c.Assert(err, gc.NotNil) 109 } 110 111 func (s *Suite) TestImport(c *gc.C) { 112 api := s.mustNewAPI(c) 113 tag := s.importModel(c, api) 114 // Check the model was imported. 115 model, err := s.State.GetModel(tag) 116 c.Assert(err, jc.ErrorIsNil) 117 c.Assert(model.Name(), gc.Equals, "some-model") 118 c.Assert(model.MigrationMode(), gc.Equals, state.MigrationModeImporting) 119 } 120 121 func (s *Suite) TestAbort(c *gc.C) { 122 api := s.mustNewAPI(c) 123 tag := s.importModel(c, api) 124 125 err := api.Abort(params.ModelArgs{ModelTag: tag.String()}) 126 c.Assert(err, jc.ErrorIsNil) 127 128 // The model should no longer exist. 129 _, err = s.State.GetModel(tag) 130 c.Assert(err, gc.ErrorMatches, `model not found`) 131 } 132 133 func (s *Suite) TestAbortNotATag(c *gc.C) { 134 api := s.mustNewAPI(c) 135 err := api.Abort(params.ModelArgs{ModelTag: "not-a-tag"}) 136 c.Assert(err, gc.ErrorMatches, `"not-a-tag" is not a valid tag`) 137 } 138 139 func (s *Suite) TestAbortMissingEnv(c *gc.C) { 140 api := s.mustNewAPI(c) 141 newUUID := utils.MustNewUUID().String() 142 err := api.Abort(params.ModelArgs{ModelTag: names.NewModelTag(newUUID).String()}) 143 c.Assert(err, gc.ErrorMatches, `model not found`) 144 } 145 146 func (s *Suite) TestAbortNotImportingEnv(c *gc.C) { 147 st := s.Factory.MakeModel(c, nil) 148 defer st.Close() 149 model, err := st.Model() 150 c.Assert(err, jc.ErrorIsNil) 151 152 api := s.mustNewAPI(c) 153 err = api.Abort(params.ModelArgs{ModelTag: model.ModelTag().String()}) 154 c.Assert(err, gc.ErrorMatches, `migration mode for the model is not importing`) 155 } 156 157 func (s *Suite) TestActivate(c *gc.C) { 158 api := s.mustNewAPI(c) 159 tag := s.importModel(c, api) 160 161 err := api.Activate(params.ModelArgs{ModelTag: tag.String()}) 162 c.Assert(err, jc.ErrorIsNil) 163 164 // The model should no longer exist. 165 model, err := s.State.GetModel(tag) 166 c.Assert(err, jc.ErrorIsNil) 167 c.Assert(model.MigrationMode(), gc.Equals, state.MigrationModeNone) 168 } 169 170 func (s *Suite) TestActivateNotATag(c *gc.C) { 171 api := s.mustNewAPI(c) 172 err := api.Activate(params.ModelArgs{ModelTag: "not-a-tag"}) 173 c.Assert(err, gc.ErrorMatches, `"not-a-tag" is not a valid tag`) 174 } 175 176 func (s *Suite) TestActivateMissingEnv(c *gc.C) { 177 api := s.mustNewAPI(c) 178 newUUID := utils.MustNewUUID().String() 179 err := api.Activate(params.ModelArgs{ModelTag: names.NewModelTag(newUUID).String()}) 180 c.Assert(err, gc.ErrorMatches, `model not found`) 181 } 182 183 func (s *Suite) TestActivateNotImportingEnv(c *gc.C) { 184 st := s.Factory.MakeModel(c, nil) 185 defer st.Close() 186 model, err := st.Model() 187 c.Assert(err, jc.ErrorIsNil) 188 189 api := s.mustNewAPI(c) 190 err = api.Activate(params.ModelArgs{ModelTag: model.ModelTag().String()}) 191 c.Assert(err, gc.ErrorMatches, `migration mode for the model is not importing`) 192 } 193 194 func (s *Suite) newAPI() (*migrationtarget.API, error) { 195 return migrationtarget.NewAPI(s.State, s.resources, s.authorizer) 196 } 197 198 func (s *Suite) mustNewAPI(c *gc.C) *migrationtarget.API { 199 api, err := s.newAPI() 200 c.Assert(err, jc.ErrorIsNil) 201 return api 202 } 203 204 func (s *Suite) makeExportedModel(c *gc.C) (string, []byte) { 205 model, err := s.State.Export() 206 c.Assert(err, jc.ErrorIsNil) 207 208 newUUID := utils.MustNewUUID().String() 209 model.UpdateConfig(map[string]interface{}{ 210 "name": "some-model", 211 "uuid": newUUID, 212 }) 213 214 bytes, err := description.Serialize(model) 215 c.Assert(err, jc.ErrorIsNil) 216 return newUUID, bytes 217 } 218 219 func (s *Suite) controllerVersion(c *gc.C) version.Number { 220 cfg, err := s.State.ModelConfig() 221 c.Assert(err, jc.ErrorIsNil) 222 vers, ok := cfg.AgentVersion() 223 c.Assert(ok, jc.IsTrue) 224 return vers 225 }