github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/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/collections/set" 8 jc "github.com/juju/testing/checkers" 9 "github.com/juju/utils" 10 gc "gopkg.in/check.v1" 11 "gopkg.in/juju/names.v2" 12 13 "github.com/juju/juju/apiserver/params" 14 "github.com/juju/juju/provider/dummy" 15 "github.com/juju/juju/state" 16 "github.com/juju/juju/storage" 17 "github.com/juju/juju/storage/poolmanager" 18 "github.com/juju/juju/storage/provider" 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": {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": {Count: &count}}) 60 } 61 62 func (s *unitStorageSuite) TestAddUnitStorageZeroCount(c *gc.C) { 63 s.createStorageBlockUnit(c) 64 cons := map[string]params.StorageConstraints{ 65 "allecto": {}} 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 sb, err := state.NewStorageBackend(s.State) 75 c.Assert(err, jc.ErrorIsNil) 76 after, err := sb.AllStorageInstances() 77 c.Assert(err, jc.ErrorIsNil) 78 c.Assert(len(after)-s.initialStorageInstancesCount, gc.Equals, 0) 79 s.assertExistingStorage(c, after) 80 } 81 82 func (s *unitStorageSuite) TestAddUnitStorageWithSize(c *gc.C) { 83 s.createStorageBlockUnit(c) 84 size := uint64(1) 85 cons := map[string]params.StorageConstraints{ 86 "allecto": {Size: &size}} 87 88 ctx := s.addUnitStorage(c, cons) 89 90 // Flush the context with a success. 91 err := ctx.Flush("success", nil) 92 c.Assert(err, gc.ErrorMatches, `.*only count can be specified.*`) 93 94 // Make sure no storage instances was added 95 sb, err := state.NewStorageBackend(s.State) 96 c.Assert(err, jc.ErrorIsNil) 97 after, err := sb.AllStorageInstances() 98 c.Assert(err, jc.ErrorIsNil) 99 c.Assert(len(after)-s.initialStorageInstancesCount, gc.Equals, 0) 100 s.assertExistingStorage(c, after) 101 } 102 103 func (s *unitStorageSuite) TestAddUnitStorageWithPool(c *gc.C) { 104 s.createStorageBlockUnit(c) 105 cons := map[string]params.StorageConstraints{ 106 "allecto": {Pool: "loop"}} 107 108 ctx := s.addUnitStorage(c, cons) 109 110 // Flush the context with a success. 111 err := ctx.Flush("success", nil) 112 c.Assert(err, gc.ErrorMatches, `.*only count can be specified.*`) 113 114 // Make sure no storage instances was added 115 sb, err := state.NewStorageBackend(s.State) 116 c.Assert(err, jc.ErrorIsNil) 117 after, err := sb.AllStorageInstances() 118 c.Assert(err, jc.ErrorIsNil) 119 c.Assert(len(after)-s.initialStorageInstancesCount, gc.Equals, 0) 120 s.assertExistingStorage(c, after) 121 } 122 123 func (s *unitStorageSuite) TestAddUnitStorageAccumulated(c *gc.C) { 124 s.createStorageBlock2Unit(c) 125 count := uint64(1) 126 s.assertUnitStorageAdded(c, 127 map[string]params.StorageConstraints{ 128 "multi2up": {Count: &count}}, 129 map[string]params.StorageConstraints{ 130 "multi1to10": {Count: &count}}) 131 } 132 133 func (s *unitStorageSuite) TestAddUnitStorageAccumulatedSame(c *gc.C) { 134 s.createStorageBlock2Unit(c) 135 count := uint64(1) 136 s.assertUnitStorageAdded(c, 137 map[string]params.StorageConstraints{ 138 "multi2up": {Count: &count}}, 139 map[string]params.StorageConstraints{ 140 "multi2up": {Count: &count}}) 141 } 142 143 func setupTestStorageSupport(c *gc.C, s *state.State) { 144 stsetts := state.NewStateSettings(s) 145 poolManager := poolmanager.New(stsetts, storage.ChainedProviderRegistry{ 146 dummy.StorageProviders(), 147 provider.CommonStorageProviders(), 148 }) 149 _, err := poolManager.Create(testPool, provider.LoopProviderType, map[string]interface{}{"it": "works"}) 150 c.Assert(err, jc.ErrorIsNil) 151 _, err = poolManager.Create(testPersistentPool, "modelscoped", map[string]interface{}{"persistent": true}) 152 c.Assert(err, jc.ErrorIsNil) 153 } 154 155 func (s *unitStorageSuite) createStorageEnabledUnit(c *gc.C) { 156 s.ch = s.AddTestingCharm(c, s.charmName) 157 s.application = s.AddTestingApplicationWithStorage(c, s.charmName, s.ch, s.initCons) 158 s.unit = s.AddUnit(c, s.application) 159 160 s.assertStorageCreated(c) 161 s.createHookSupport(c) 162 } 163 164 func (s *unitStorageSuite) createStorageBlockUnit(c *gc.C) { 165 s.charmName = "storage-block" 166 s.initCons = map[string]state.StorageConstraints{ 167 "data": makeStorageCons("block", 1024, 1), 168 } 169 s.createStorageEnabledUnit(c) 170 s.assertStorageCreated(c) 171 s.createHookSupport(c) 172 } 173 174 func (s *unitStorageSuite) createStorageBlock2Unit(c *gc.C) { 175 s.charmName = "storage-block2" 176 s.initCons = map[string]state.StorageConstraints{ 177 "multi1to10": makeStorageCons("loop", 0, 3), 178 } 179 s.createStorageEnabledUnit(c) 180 s.assertStorageCreated(c) 181 s.createHookSupport(c) 182 } 183 184 func (s *unitStorageSuite) assertStorageCreated(c *gc.C) { 185 sb, err := state.NewStorageBackend(s.State) 186 c.Assert(err, jc.ErrorIsNil) 187 all, err := sb.AllStorageInstances() 188 c.Assert(err, jc.ErrorIsNil) 189 s.initialStorageInstancesCount = len(all) 190 s.expectedStorageNames = set.NewStrings() 191 for _, one := range all { 192 s.expectedStorageNames.Add(one.StorageName()) 193 } 194 } 195 196 func (s *unitStorageSuite) createHookSupport(c *gc.C) { 197 password, err := utils.RandomPassword() 198 err = s.unit.SetPassword(password) 199 c.Assert(err, jc.ErrorIsNil) 200 s.st = s.OpenAPIAs(c, s.unit.Tag(), password) 201 s.uniter, err = s.st.Uniter() 202 c.Assert(err, jc.ErrorIsNil) 203 c.Assert(s.uniter, gc.NotNil) 204 s.apiUnit, err = s.uniter.Unit(s.unit.Tag().(names.UnitTag)) 205 c.Assert(err, jc.ErrorIsNil) 206 207 err = s.unit.SetCharmURL(s.ch.URL()) 208 c.Assert(err, jc.ErrorIsNil) 209 } 210 211 func makeStorageCons(pool string, size, count uint64) state.StorageConstraints { 212 return state.StorageConstraints{Pool: pool, Size: size, Count: count} 213 } 214 215 func (s *unitStorageSuite) addUnitStorage(c *gc.C, cons ...map[string]params.StorageConstraints) *context.HookContext { 216 // Get the context. 217 ctx := s.getHookContext(c, s.State.ModelUUID(), -1, "") 218 c.Assert(ctx.UnitName(), gc.Equals, s.unit.Name()) 219 220 for _, one := range cons { 221 for storage := range one { 222 s.expectedStorageNames.Add(storage) 223 } 224 ctx.AddUnitStorage(one) 225 } 226 return ctx 227 } 228 229 func (s *unitStorageSuite) assertUnitStorageAdded(c *gc.C, cons ...map[string]params.StorageConstraints) { 230 ctx := s.addUnitStorage(c, cons...) 231 232 // Flush the context with a success. 233 err := ctx.Flush("success", nil) 234 c.Assert(err, jc.ErrorIsNil) 235 236 sb, err := state.NewStorageBackend(s.State) 237 c.Assert(err, jc.ErrorIsNil) 238 after, err := sb.AllStorageInstances() 239 c.Assert(err, jc.ErrorIsNil) 240 c.Assert(len(after)-s.initialStorageInstancesCount, gc.Equals, len(cons)) 241 s.assertExistingStorage(c, after) 242 } 243 244 func (s *unitStorageSuite) assertExistingStorage(c *gc.C, all []state.StorageInstance) { 245 for _, one := range all { 246 c.Assert(s.expectedStorageNames.Contains(one.StorageName()), jc.IsTrue) 247 } 248 }