github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/worker/uniter/runner/context/unitStorage_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package context_test 5 6 import ( 7 "github.com/juju/names" 8 jc "github.com/juju/testing/checkers" 9 "github.com/juju/utils" 10 "github.com/juju/utils/set" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/apiserver/params" 14 "github.com/juju/juju/provider/ec2" 15 "github.com/juju/juju/state" 16 "github.com/juju/juju/storage/poolmanager" 17 "github.com/juju/juju/storage/provider" 18 "github.com/juju/juju/storage/provider/registry" 19 "github.com/juju/juju/worker/uniter/runner/context" 20 ) 21 22 type unitStorageSuite struct { 23 HookContextSuite 24 expectedStorageNames set.Strings 25 charmName string 26 initCons map[string]state.StorageConstraints 27 ch *state.Charm 28 initialStorageInstancesCount int 29 } 30 31 var _ = gc.Suite(&unitStorageSuite{}) 32 33 const ( 34 testPool = "block" 35 testPersistentPool = "block-persistent" 36 ) 37 38 func (s *unitStorageSuite) SetUpTest(c *gc.C) { 39 s.HookContextSuite.SetUpTest(c) 40 setupTestStorageSupport(c, s.State) 41 } 42 43 func (s *unitStorageSuite) TestAddUnitStorage(c *gc.C) { 44 s.createStorageBlockUnit(c) 45 count := uint64(1) 46 s.assertUnitStorageAdded(c, 47 map[string]params.StorageConstraints{ 48 "allecto": params.StorageConstraints{Count: &count}}) 49 } 50 51 func (s *unitStorageSuite) TestAddUnitStorageIgnoresBlocks(c *gc.C) { 52 s.createStorageBlockUnit(c) 53 count := uint64(1) 54 s.BlockDestroyModel(c, "TestAddUnitStorageIgnoresBlocks") 55 s.BlockRemoveObject(c, "TestAddUnitStorageIgnoresBlocks") 56 s.BlockAllChanges(c, "TestAddUnitStorageIgnoresBlocks") 57 s.assertUnitStorageAdded(c, 58 map[string]params.StorageConstraints{ 59 "allecto": params.StorageConstraints{Count: &count}}) 60 } 61 62 func (s *unitStorageSuite) TestAddUnitStorageZeroCount(c *gc.C) { 63 s.createStorageBlockUnit(c) 64 cons := map[string]params.StorageConstraints{ 65 "allecto": params.StorageConstraints{}} 66 67 ctx := s.addUnitStorage(c, cons) 68 69 // Flush the context with a success. 70 err := ctx.Flush("success", nil) 71 c.Assert(err, gc.ErrorMatches, `.*count must be specified.*`) 72 73 // Make sure no storage instances was added 74 after, err := s.State.AllStorageInstances() 75 c.Assert(err, jc.ErrorIsNil) 76 c.Assert(len(after)-s.initialStorageInstancesCount, gc.Equals, 0) 77 s.assertExistingStorage(c, after) 78 } 79 80 func (s *unitStorageSuite) TestAddUnitStorageWithSize(c *gc.C) { 81 s.createStorageBlockUnit(c) 82 size := uint64(1) 83 cons := map[string]params.StorageConstraints{ 84 "allecto": params.StorageConstraints{Size: &size}} 85 86 ctx := s.addUnitStorage(c, cons) 87 88 // Flush the context with a success. 89 err := ctx.Flush("success", nil) 90 c.Assert(err, gc.ErrorMatches, `.*only count can be specified.*`) 91 92 // Make sure no storage instances was added 93 after, err := s.State.AllStorageInstances() 94 c.Assert(err, jc.ErrorIsNil) 95 c.Assert(len(after)-s.initialStorageInstancesCount, gc.Equals, 0) 96 s.assertExistingStorage(c, after) 97 } 98 99 func (s *unitStorageSuite) TestAddUnitStorageWithPool(c *gc.C) { 100 s.createStorageBlockUnit(c) 101 cons := map[string]params.StorageConstraints{ 102 "allecto": params.StorageConstraints{Pool: "loop"}} 103 104 ctx := s.addUnitStorage(c, cons) 105 106 // Flush the context with a success. 107 err := ctx.Flush("success", nil) 108 c.Assert(err, gc.ErrorMatches, `.*only count can be specified.*`) 109 110 // Make sure no storage instances was added 111 after, err := s.State.AllStorageInstances() 112 c.Assert(err, jc.ErrorIsNil) 113 c.Assert(len(after)-s.initialStorageInstancesCount, gc.Equals, 0) 114 s.assertExistingStorage(c, after) 115 } 116 117 func (s *unitStorageSuite) TestAddUnitStorageAccumulated(c *gc.C) { 118 s.createStorageBlock2Unit(c) 119 count := uint64(1) 120 s.assertUnitStorageAdded(c, 121 map[string]params.StorageConstraints{ 122 "multi2up": params.StorageConstraints{Count: &count}}, 123 map[string]params.StorageConstraints{ 124 "multi1to10": params.StorageConstraints{Count: &count}}) 125 } 126 127 func (s *unitStorageSuite) TestAddUnitStorageAccumulatedSame(c *gc.C) { 128 s.createStorageBlock2Unit(c) 129 count := uint64(1) 130 s.assertUnitStorageAdded(c, 131 map[string]params.StorageConstraints{ 132 "multi2up": params.StorageConstraints{Count: &count}}, 133 map[string]params.StorageConstraints{ 134 "multi2up": params.StorageConstraints{Count: &count}}) 135 } 136 137 func setupTestStorageSupport(c *gc.C, s *state.State) { 138 stsetts := state.NewStateSettings(s) 139 poolManager := poolmanager.New(stsetts) 140 _, err := poolManager.Create(testPool, provider.LoopProviderType, map[string]interface{}{"it": "works"}) 141 c.Assert(err, jc.ErrorIsNil) 142 _, err = poolManager.Create(testPersistentPool, ec2.EBS_ProviderType, map[string]interface{}{"persistent": true}) 143 c.Assert(err, jc.ErrorIsNil) 144 145 registry.RegisterEnvironStorageProviders("dummy", ec2.EBS_ProviderType) 146 registry.RegisterEnvironStorageProviders("admin", ec2.EBS_ProviderType) 147 } 148 149 func (s *unitStorageSuite) createStorageEnabledUnit(c *gc.C) { 150 s.ch = s.AddTestingCharm(c, s.charmName) 151 s.service = s.AddTestingServiceWithStorage(c, s.charmName, s.ch, s.initCons) 152 s.unit = s.AddUnit(c, s.service) 153 154 s.assertStorageCreated(c) 155 s.createHookSupport(c) 156 } 157 158 func (s *unitStorageSuite) createStorageBlockUnit(c *gc.C) { 159 s.charmName = "storage-block" 160 s.initCons = map[string]state.StorageConstraints{ 161 "data": makeStorageCons("block", 1024, 1), 162 } 163 s.createStorageEnabledUnit(c) 164 s.assertStorageCreated(c) 165 s.createHookSupport(c) 166 } 167 168 func (s *unitStorageSuite) createStorageBlock2Unit(c *gc.C) { 169 s.charmName = "storage-block2" 170 s.initCons = map[string]state.StorageConstraints{ 171 "multi1to10": makeStorageCons("loop", 0, 3), 172 } 173 s.createStorageEnabledUnit(c) 174 s.assertStorageCreated(c) 175 s.createHookSupport(c) 176 } 177 178 func (s *unitStorageSuite) assertStorageCreated(c *gc.C) { 179 all, err := s.State.AllStorageInstances() 180 c.Assert(err, jc.ErrorIsNil) 181 s.initialStorageInstancesCount = len(all) 182 s.expectedStorageNames = set.NewStrings() 183 for _, one := range all { 184 s.expectedStorageNames.Add(one.StorageName()) 185 } 186 } 187 188 func (s *unitStorageSuite) createHookSupport(c *gc.C) { 189 password, err := utils.RandomPassword() 190 err = s.unit.SetPassword(password) 191 c.Assert(err, jc.ErrorIsNil) 192 s.st = s.OpenAPIAs(c, s.unit.Tag(), password) 193 s.uniter, err = s.st.Uniter() 194 c.Assert(err, jc.ErrorIsNil) 195 c.Assert(s.uniter, gc.NotNil) 196 s.apiUnit, err = s.uniter.Unit(s.unit.Tag().(names.UnitTag)) 197 c.Assert(err, jc.ErrorIsNil) 198 199 err = s.unit.SetCharmURL(s.ch.URL()) 200 c.Assert(err, jc.ErrorIsNil) 201 } 202 203 func makeStorageCons(pool string, size, count uint64) state.StorageConstraints { 204 return state.StorageConstraints{Pool: pool, Size: size, Count: count} 205 } 206 207 func (s *unitStorageSuite) addUnitStorage(c *gc.C, cons ...map[string]params.StorageConstraints) *context.HookContext { 208 // Get the context. 209 ctx := s.getHookContext(c, s.State.ModelUUID(), -1, "", noProxies) 210 c.Assert(ctx.UnitName(), gc.Equals, s.unit.Name()) 211 212 for _, one := range cons { 213 for storage, _ := range one { 214 s.expectedStorageNames.Add(storage) 215 } 216 ctx.AddUnitStorage(one) 217 } 218 return ctx 219 } 220 221 func (s *unitStorageSuite) assertUnitStorageAdded(c *gc.C, cons ...map[string]params.StorageConstraints) { 222 ctx := s.addUnitStorage(c, cons...) 223 224 // Flush the context with a success. 225 err := ctx.Flush("success", nil) 226 c.Assert(err, jc.ErrorIsNil) 227 228 after, err := s.State.AllStorageInstances() 229 c.Assert(err, jc.ErrorIsNil) 230 c.Assert(len(after)-s.initialStorageInstancesCount, gc.Equals, len(cons)) 231 s.assertExistingStorage(c, after) 232 } 233 234 func (s *unitStorageSuite) assertExistingStorage(c *gc.C, all []state.StorageInstance) { 235 for _, one := range all { 236 c.Assert(s.expectedStorageNames.Contains(one.StorageName()), jc.IsTrue) 237 } 238 }