func (s *storageSuite) TestWatchUnitStorageAttachments(c *gc.C) { resources := common.NewResources() getCanAccess := func() (common.AuthFunc, error) { return func(names.Tag) bool { return true }, nil } unitTag := names.NewUnitTag("mysql/0") watcher := &mockStringsWatcher{ changes: make(chan []string, 1), } watcher.changes <- []string{"storage/0", "storage/1"} state := &mockStorageState{ watchStorageAttachments: func(u names.UnitTag) state.StringsWatcher { c.Assert(u, gc.DeepEquals, unitTag) return watcher }, } storage, err := uniter.NewStorageAPI(state, resources, getCanAccess) c.Assert(err, jc.ErrorIsNil) watches, err := storage.WatchUnitStorageAttachments(params.Entities{ Entities: []params.Entity{{unitTag.String()}}, }) c.Assert(err, jc.ErrorIsNil) c.Assert(watches, gc.DeepEquals, params.StringsWatchResults{ Results: []params.StringsWatchResult{{ StringsWatcherId: "1", Changes: []string{"storage/0", "storage/1"}, }}, }) c.Assert(resources.Get("1"), gc.Equals, watcher) }
func (s *storageSuite) TestDestroyUnitStorageAttachments(c *gc.C) { resources := common.NewResources() getCanAccess := func() (common.AuthFunc, error) { return func(names.Tag) bool { return true }, nil } unitTag := names.NewUnitTag("mysql/0") var calls []string state := &mockStorageState{ destroyUnitStorageAttachments: func(u names.UnitTag) error { calls = append(calls, "DestroyUnitStorageAttachments") c.Assert(u, gc.DeepEquals, unitTag) return nil }, } storage, err := uniter.NewStorageAPI(state, resources, getCanAccess) c.Assert(err, jc.ErrorIsNil) errors, err := storage.DestroyUnitStorageAttachments(params.Entities{ Entities: []params.Entity{{ Tag: unitTag.String(), }}, }) c.Assert(err, jc.ErrorIsNil) c.Assert(calls, jc.DeepEquals, []string{"DestroyUnitStorageAttachments"}) c.Assert(errors, jc.DeepEquals, params.ErrorResults{ []params.ErrorResult{{}}, }) }
func (s *storageSuite) TestRemoveStorageAttachments(c *gc.C) { setMock := func(st *mockStorageState, f func(s names.StorageTag, u names.UnitTag) error) { st.remove = f } unitTag0 := names.NewUnitTag("mysql/0") unitTag1 := names.NewUnitTag("mysql/1") storageTag0 := names.NewStorageTag("data/0") storageTag1 := names.NewStorageTag("data/1") resources := common.NewResources() getCanAccess := func() (common.AuthFunc, error) { return func(tag names.Tag) bool { return tag == unitTag0 }, nil } state := &mockStorageState{} setMock(state, func(s names.StorageTag, u names.UnitTag) error { c.Assert(u, gc.DeepEquals, unitTag0) if s == storageTag1 { return errors.New("badness") } return nil }) storage, err := uniter.NewStorageAPI(state, resources, getCanAccess) c.Assert(err, jc.ErrorIsNil) errors, err := storage.RemoveStorageAttachments(params.StorageAttachmentIds{ Ids: []params.StorageAttachmentId{{ StorageTag: storageTag0.String(), UnitTag: unitTag0.String(), }, { StorageTag: storageTag1.String(), UnitTag: unitTag0.String(), }, { StorageTag: storageTag0.String(), UnitTag: unitTag1.String(), }, { StorageTag: unitTag0.String(), // oops UnitTag: unitTag0.String(), }, { StorageTag: storageTag0.String(), UnitTag: storageTag0.String(), // oops }}, }) c.Assert(err, jc.ErrorIsNil) c.Assert(errors, jc.DeepEquals, params.ErrorResults{ Results: []params.ErrorResult{ {nil}, {¶ms.Error{Message: "badness"}}, {¶ms.Error{Code: params.CodeUnauthorized, Message: "permission denied"}}, {¶ms.Error{Message: `"unit-mysql-0" is not a valid storage tag`}}, {¶ms.Error{Message: `"storage-data-0" is not a valid unit tag`}}, }, }) }
func (s *storageSuite) TestWatchStorageAttachmentVolume(c *gc.C) { resources := common.NewResources() getCanAccess := func() (common.AuthFunc, error) { return func(names.Tag) bool { return true }, nil } unitTag := names.NewUnitTag("mysql/0") storageTag := names.NewStorageTag("data/0") machineTag := names.NewMachineTag("66") volumeTag := names.NewVolumeTag("104") volume := &mockVolume{tag: volumeTag} storageInstance := &mockStorageInstance{kind: state.StorageKindBlock} storageWatcher := &mockNotifyWatcher{ changes: make(chan struct{}, 1), } storageWatcher.changes <- struct{}{} volumeWatcher := &mockNotifyWatcher{ changes: make(chan struct{}, 1), } volumeWatcher.changes <- struct{}{} blockDevicesWatcher := &mockNotifyWatcher{ changes: make(chan struct{}, 1), } blockDevicesWatcher.changes <- struct{}{} var calls []string state := &mockStorageState{ storageInstance: func(s names.StorageTag) (state.StorageInstance, error) { calls = append(calls, "StorageInstance") c.Assert(s, gc.DeepEquals, storageTag) return storageInstance, nil }, storageInstanceVolume: func(s names.StorageTag) (state.Volume, error) { calls = append(calls, "StorageInstanceVolume") c.Assert(s, gc.DeepEquals, storageTag) return volume, nil }, unitAssignedMachine: func(u names.UnitTag) (names.MachineTag, error) { calls = append(calls, "UnitAssignedMachine") c.Assert(u, gc.DeepEquals, unitTag) return machineTag, nil }, watchStorageAttachment: func(s names.StorageTag, u names.UnitTag) state.NotifyWatcher { calls = append(calls, "WatchStorageAttachment") c.Assert(s, gc.DeepEquals, storageTag) c.Assert(u, gc.DeepEquals, unitTag) return storageWatcher }, watchVolumeAttachment: func(m names.MachineTag, v names.VolumeTag) state.NotifyWatcher { calls = append(calls, "WatchVolumeAttachment") c.Assert(m, gc.DeepEquals, machineTag) c.Assert(v, gc.DeepEquals, volumeTag) return volumeWatcher }, watchBlockDevices: func(m names.MachineTag) state.NotifyWatcher { calls = append(calls, "WatchBlockDevices") c.Assert(m, gc.DeepEquals, machineTag) return blockDevicesWatcher }, } storage, err := uniter.NewStorageAPI(state, resources, getCanAccess) c.Assert(err, jc.ErrorIsNil) watches, err := storage.WatchStorageAttachments(params.StorageAttachmentIds{ Ids: []params.StorageAttachmentId{{ StorageTag: storageTag.String(), UnitTag: unitTag.String(), }}, }) c.Assert(err, jc.ErrorIsNil) c.Assert(watches, gc.DeepEquals, params.NotifyWatchResults{ Results: []params.NotifyWatchResult{{ NotifyWatcherId: "1", }}, }) c.Assert(calls, gc.DeepEquals, []string{ "UnitAssignedMachine", "StorageInstance", "StorageInstanceVolume", "WatchVolumeAttachment", "WatchBlockDevices", "WatchStorageAttachment", }) }
func (s *storageSuite) TestAddUnitStorage(c *gc.C) { setMockConstraints := func(st *mockStorageState, f func(u names.UnitTag) (map[string]state.StorageConstraints, error)) { st.unitStorageConstraints = f } setMockAdd := func(st *mockStorageState, f func(tag names.UnitTag, name string, cons state.StorageConstraints) error) { st.addUnitStorage = f } unitTag0 := names.NewUnitTag("mysql/0") storageName0 := "data" storageName1 := "store" unitPool := "real" size := uint64(3) unitSize := size * 2 unitCount := uint64(100) testCount := uint64(10) resources := common.NewResources() getCanAccess := func() (common.AuthFunc, error) { return func(tag names.Tag) bool { return tag == unitTag0 }, nil } s.called = []string{} mockState := &mockStorageState{} setMockConstraints(mockState, func(u names.UnitTag) (map[string]state.StorageConstraints, error) { s.called = append(s.called, unitConstraintsCall) c.Assert(u, gc.DeepEquals, unitTag0) return map[string]state.StorageConstraints{ storageName0: state.StorageConstraints{ Pool: unitPool, Size: unitSize, Count: unitCount, }, storageName1: state.StorageConstraints{}, }, nil }) setMockAdd(mockState, func(u names.UnitTag, name string, cons state.StorageConstraints) error { s.called = append(s.called, addStorageCall) c.Assert(u, gc.DeepEquals, unitTag0) if name == storageName1 { return errors.New("badness") } c.Assert(cons.Count, gc.Not(gc.Equals), unitCount) c.Assert(cons.Count, jc.DeepEquals, testCount) c.Assert(cons.Pool, jc.DeepEquals, unitPool) c.Assert(cons.Size, jc.DeepEquals, unitSize) return nil }) storage, err := uniter.NewStorageAPI(mockState, resources, getCanAccess) c.Assert(err, jc.ErrorIsNil) errors, err := storage.AddUnitStorage(params.StoragesAddParams{ Storages: []params.StorageAddParams{ { UnitTag: unitTag0.String(), StorageName: storageName0, Constraints: params.StorageConstraints{Count: &testCount}, }, { UnitTag: unitTag0.String(), StorageName: storageName1, Constraints: params.StorageConstraints{Count: &testCount}, }, }}, ) c.Assert(err, jc.ErrorIsNil) c.Assert(s.called, jc.SameContents, []string{ unitConstraintsCall, addStorageCall, unitConstraintsCall, addStorageCall, }) c.Assert(errors, jc.DeepEquals, params.ErrorResults{ Results: []params.ErrorResult{ {nil}, {¶ms.Error{Message: "adding storage store for unit-mysql-0: badness"}}, }, }) }
func (s *storageSuite) TestAddUnitStorageConstraintsErrors(c *gc.C) { setMockConstraints := func(st *mockStorageState, f func(u names.UnitTag) (map[string]state.StorageConstraints, error)) { st.unitStorageConstraints = f } unitTag0 := names.NewUnitTag("mysql/0") storageName0 := "data" storageName1 := "store" resources := common.NewResources() getCanAccess := func() (common.AuthFunc, error) { return func(tag names.Tag) bool { return tag == unitTag0 }, nil } s.called = []string{} mockState := &mockStorageState{} setMockConstraints(mockState, func(u names.UnitTag) (map[string]state.StorageConstraints, error) { s.called = append(s.called, unitConstraintsCall) c.Assert(u, gc.DeepEquals, unitTag0) return map[string]state.StorageConstraints{ storageName0: state.StorageConstraints{}, }, nil }) storage, err := uniter.NewStorageAPI(mockState, resources, getCanAccess) c.Assert(err, jc.ErrorIsNil) size := uint64(10) count := uint64(0) errors, err := storage.AddUnitStorage(params.StoragesAddParams{ Storages: []params.StorageAddParams{ { UnitTag: unitTag0.String(), StorageName: storageName0, Constraints: params.StorageConstraints{Pool: "matter"}, }, { UnitTag: unitTag0.String(), StorageName: storageName0, Constraints: params.StorageConstraints{Size: &size}, }, { UnitTag: unitTag0.String(), StorageName: storageName0, Constraints: params.StorageConstraints{}, }, { UnitTag: unitTag0.String(), StorageName: storageName0, Constraints: params.StorageConstraints{Count: &count}, }, { UnitTag: unitTag0.String(), StorageName: storageName1, Constraints: params.StorageConstraints{}, }, }}, ) c.Assert(err, jc.ErrorIsNil) c.Assert(s.called, jc.SameContents, []string{ unitConstraintsCall, unitConstraintsCall, unitConstraintsCall, unitConstraintsCall, unitConstraintsCall, }) c.Assert(errors, jc.DeepEquals, params.ErrorResults{ Results: []params.ErrorResult{ {¶ms.Error{Message: `adding storage data for unit-mysql-0: only count can be specified`}}, {¶ms.Error{Message: `adding storage data for unit-mysql-0: only count can be specified`}}, {¶ms.Error{Message: `adding storage data for unit-mysql-0: count must be specified`}}, {¶ms.Error{Message: `adding storage data for unit-mysql-0: count must be specified`}}, {¶ms.Error{ Code: "not found", Message: "adding storage store for unit-mysql-0: storage \"store\" not found"}}, }, }) }