github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/apiserver/diskformatter/diskformatter_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package diskformatter_test 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/names" 9 jc "github.com/juju/testing/checkers" 10 gc "gopkg.in/check.v1" 11 12 "github.com/juju/juju/api/watcher" 13 "github.com/juju/juju/apiserver/common" 14 "github.com/juju/juju/apiserver/diskformatter" 15 "github.com/juju/juju/apiserver/params" 16 apiservertesting "github.com/juju/juju/apiserver/testing" 17 "github.com/juju/juju/state" 18 "github.com/juju/juju/storage" 19 coretesting "github.com/juju/juju/testing" 20 ) 21 22 var _ = gc.Suite(&DiskFormatterSuite{}) 23 24 type DiskFormatterSuite struct { 25 coretesting.BaseSuite 26 resources *common.Resources 27 authorizer *apiservertesting.FakeAuthorizer 28 tag names.UnitTag 29 st *mockState 30 api *diskformatter.DiskFormatterAPI 31 } 32 33 func (s *DiskFormatterSuite) SetUpTest(c *gc.C) { 34 s.BaseSuite.SetUpTest(c) 35 s.resources = common.NewResources() 36 s.tag = names.NewUnitTag("service/0") 37 s.authorizer = &apiservertesting.FakeAuthorizer{Tag: s.tag} 38 s.st = &mockState{} 39 diskformatter.PatchState(s, s.st) 40 41 var err error 42 s.api, err = diskformatter.NewDiskFormatterAPI(nil, s.resources, s.authorizer) 43 c.Assert(err, jc.ErrorIsNil) 44 } 45 46 func (s *DiskFormatterSuite) TestWatchBlockDevices(c *gc.C) { 47 results, err := s.api.WatchBlockDevices(params.Entities{ 48 Entities: []params.Entity{ 49 {Tag: "unit-service-0"}, 50 {Tag: "disk-1"}, 51 }, 52 }) 53 c.Assert(err, jc.ErrorIsNil) 54 c.Assert(results, gc.DeepEquals, params.StringsWatchResults{ 55 Results: []params.StringsWatchResult{ 56 {Error: ¶ms.Error{Message: "WatchUnitMachineBlockDevices fails", Code: ""}}, 57 // disk-1 does not exist, so we get ErrPerm. 58 {Error: ¶ms.Error{Message: "permission denied", Code: "unauthorized access"}}, 59 }, 60 }) 61 c.Assert(s.st.calls, gc.DeepEquals, []string{"WatchUnitMachineBlockDevices"}) 62 c.Assert(s.st.unitTags, gc.DeepEquals, []names.UnitTag{s.tag}) 63 } 64 65 func (s *DiskFormatterSuite) TestBlockDevices(c *gc.C) { 66 s.st.devices = map[string]state.BlockDevice{ 67 "0": &mockBlockDevice{ 68 name: "0", 69 storageInstance: "storage/0", 70 info: &state.BlockDeviceInfo{}, 71 attached: true, 72 }, 73 "1": &mockBlockDevice{ 74 storageInstance: "storage/1", 75 attached: true, 76 }, 77 "2": &mockBlockDevice{ 78 attached: true, 79 }, 80 "3": &mockBlockDevice{ 81 name: "3", 82 storageInstance: "storage/0", 83 attached: true, 84 }, 85 "4": &mockBlockDevice{ 86 attached: false, 87 }, 88 } 89 s.st.storageInstances = map[string]state.StorageInstance{ 90 "storage/0": &mockStorageInstance{owner: s.tag}, 91 "storage/1": &mockStorageInstance{owner: names.NewServiceTag("mysql")}, 92 } 93 94 results, err := s.api.BlockDevices(params.Entities{ 95 Entities: []params.Entity{ 96 {Tag: "disk-0"}, 97 {Tag: "disk-1"}, // different owner 98 {Tag: "disk-2"}, // no storage instance 99 {Tag: "disk-3"}, // not provisioned 100 {Tag: "disk-4"}, // unattached 101 {Tag: "disk-5"}, // missing 102 }, 103 }) 104 c.Assert(err, jc.ErrorIsNil) 105 c.Assert(results, gc.DeepEquals, params.BlockDeviceResults{ 106 Results: []params.BlockDeviceResult{ 107 {Result: storage.BlockDevice{Name: "0"}}, 108 {Error: ¶ms.Error{Message: "permission denied", Code: "unauthorized access"}}, 109 {Error: ¶ms.Error{Message: "permission denied", Code: "unauthorized access"}}, 110 {Error: ¶ms.Error{Message: `block device "3" not provisioned`, Code: "not provisioned"}}, 111 {Error: ¶ms.Error{Message: "permission denied", Code: "unauthorized access"}}, 112 {Error: ¶ms.Error{Message: "permission denied", Code: "unauthorized access"}}, 113 }, 114 }) 115 c.Assert(s.st.calls, gc.DeepEquals, []string{ 116 "BlockDevice", "StorageInstance", 117 "BlockDevice", "StorageInstance", 118 "BlockDevice", // no storage instance 119 "BlockDevice", "StorageInstance", 120 "BlockDevice", // unattached 121 "BlockDevice", // missing 122 }) 123 c.Assert(s.st.blockDeviceNames, gc.DeepEquals, []string{ 124 "0", "1", "2", "3", "4", "5", 125 }) 126 c.Assert(s.st.storageInstanceIds, gc.DeepEquals, []string{ 127 "storage/0", "storage/1", "storage/0", 128 }) 129 } 130 131 func (s *DiskFormatterSuite) TestBlockDeviceStorageInstances(c *gc.C) { 132 s.st.devices = map[string]state.BlockDevice{ 133 "0": &mockBlockDevice{ 134 name: "0", 135 storageInstance: "storage/0", 136 info: &state.BlockDeviceInfo{}, 137 attached: true, 138 }, 139 "1": &mockBlockDevice{ 140 name: "1", 141 storageInstance: "storage/1", 142 info: &state.BlockDeviceInfo{}, 143 attached: true, 144 }, 145 } 146 s.st.storageInstances = map[string]state.StorageInstance{ 147 "storage/0": &mockStorageInstance{ 148 id: "storage/0", 149 owner: s.tag, 150 kind: state.StorageKindBlock, 151 }, 152 "storage/1": &mockStorageInstance{ 153 id: "storage/1", 154 owner: s.tag, 155 kind: state.StorageKindFilesystem, 156 }, 157 } 158 159 results, err := s.api.BlockDeviceStorageInstances(params.Entities{ 160 Entities: []params.Entity{{Tag: "disk-0"}, {Tag: "disk-1"}}, 161 }) 162 c.Assert(err, jc.ErrorIsNil) 163 c.Assert(results, gc.DeepEquals, params.StorageInstanceResults{ 164 Results: []params.StorageInstanceResult{ 165 {Result: storage.StorageInstance{ 166 Id: "storage/0", 167 Kind: storage.StorageKindBlock, 168 }}, 169 {Result: storage.StorageInstance{ 170 Id: "storage/1", 171 Kind: storage.StorageKindFilesystem, 172 }}, 173 }, 174 }) 175 c.Assert(s.st.calls, gc.DeepEquals, []string{ 176 "BlockDevice", "StorageInstance", 177 "BlockDevice", "StorageInstance", 178 }) 179 c.Assert(s.st.blockDeviceNames, gc.DeepEquals, []string{ 180 "0", "1", 181 }) 182 c.Assert(s.st.storageInstanceIds, gc.DeepEquals, []string{ 183 "storage/0", "storage/1", 184 }) 185 } 186 187 type mockState struct { 188 calls []string 189 devices map[string]state.BlockDevice 190 storageInstances map[string]state.StorageInstance 191 192 unitTags []names.UnitTag 193 blockDeviceNames []string 194 storageInstanceIds []string 195 } 196 197 func (st *mockState) WatchUnitMachineBlockDevices(tag names.UnitTag) (watcher.StringsWatcher, error) { 198 st.calls = append(st.calls, "WatchUnitMachineBlockDevices") 199 st.unitTags = append(st.unitTags, tag) 200 return nil, errors.New("WatchUnitMachineBlockDevices fails") 201 } 202 203 func (st *mockState) BlockDevice(name string) (state.BlockDevice, error) { 204 st.calls = append(st.calls, "BlockDevice") 205 st.blockDeviceNames = append(st.blockDeviceNames, name) 206 blockDevice, ok := st.devices[name] 207 if !ok { 208 return nil, errors.NotFoundf("block device %q", name) 209 } 210 return blockDevice, nil 211 } 212 213 func (st *mockState) StorageInstance(id string) (state.StorageInstance, error) { 214 st.calls = append(st.calls, "StorageInstance") 215 st.storageInstanceIds = append(st.storageInstanceIds, id) 216 storageInstance, ok := st.storageInstances[id] 217 if !ok { 218 return nil, errors.NotFoundf("storage instance %q", id) 219 } 220 return storageInstance, nil 221 } 222 223 type mockBlockDevice struct { 224 state.BlockDevice 225 name string 226 storageInstance string 227 attached bool 228 info *state.BlockDeviceInfo 229 } 230 231 func (d *mockBlockDevice) Name() string { 232 return d.name 233 } 234 235 func (d *mockBlockDevice) Attached() bool { 236 return d.attached 237 } 238 239 func (d *mockBlockDevice) Info() (state.BlockDeviceInfo, error) { 240 if d.info == nil { 241 return state.BlockDeviceInfo{}, errors.NotProvisionedf("block device %q", d.name) 242 } 243 return *d.info, nil 244 } 245 246 func (d *mockBlockDevice) StorageInstance() (string, bool) { 247 return d.storageInstance, d.storageInstance != "" 248 } 249 250 type mockStorageInstance struct { 251 state.StorageInstance 252 id string 253 owner names.Tag 254 kind state.StorageKind 255 } 256 257 func (d *mockStorageInstance) Id() string { 258 return d.id 259 } 260 261 func (d *mockStorageInstance) Owner() names.Tag { 262 return d.owner 263 } 264 265 func (d *mockStorageInstance) Kind() state.StorageKind { 266 return d.kind 267 }