1
// Copyright 2014 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
7
jc "github.com/juju/testing/checkers"
9
"gopkg.in/juju/names.v2"
11
"github.com/juju/juju/instance"
12
"github.com/juju/juju/provider/gce"
13
"github.com/juju/juju/provider/gce/google"
14
"github.com/juju/juju/storage"
17
type storageProviderSuite struct {
19
provider storage.Provider
22
var _ = gc.Suite(&storageProviderSuite{})
24
func (s *storageProviderSuite) SetUpTest(c *gc.C) {
25
s.BaseSuite.SetUpTest(c)
28
s.provider, err = s.Env.StorageProvider("gce")
29
c.Assert(err, jc.ErrorIsNil)
32
func (s *storageProviderSuite) TestValidateConfig(c *gc.C) {
33
// ValidateConfig performs no validation at all yet, this test
34
// it is just here to make sure that the placeholder will
36
cfg := &storage.Config{}
37
err := s.provider.ValidateConfig(cfg)
38
c.Check(err, jc.ErrorIsNil)
41
func (s *storageProviderSuite) TestBlockStorageSupport(c *gc.C) {
42
supports := s.provider.Supports(storage.StorageKindBlock)
43
c.Check(supports, jc.IsTrue)
46
func (s *storageProviderSuite) TestFSStorageSupport(c *gc.C) {
47
supports := s.provider.Supports(storage.StorageKindFilesystem)
48
c.Check(supports, jc.IsFalse)
51
func (s *storageProviderSuite) TestFSSource(c *gc.C) {
52
sConfig := &storage.Config{}
53
_, err := s.provider.FilesystemSource(sConfig)
54
c.Check(err, gc.ErrorMatches, "filesystems not supported")
57
func (s *storageProviderSuite) TestVolumeSource(c *gc.C) {
58
storageCfg := &storage.Config{}
59
_, err := s.provider.VolumeSource(storageCfg)
60
c.Check(err, jc.ErrorIsNil)
63
type volumeSourceSuite struct {
65
source storage.VolumeSource
66
params []storage.VolumeParams
68
attachmentParams *storage.VolumeAttachmentParams
71
var _ = gc.Suite(&volumeSourceSuite{})
73
func (s *volumeSourceSuite) SetUpTest(c *gc.C) {
74
s.BaseSuite.SetUpTest(c)
76
provider, err := s.Env.StorageProvider("gce")
77
c.Assert(err, jc.ErrorIsNil)
78
s.source, err = provider.VolumeSource(&storage.Config{})
79
c.Check(err, jc.ErrorIsNil)
81
inst := gce.NewInstance(s.BaseInstance, s.Env)
82
vTag := names.NewVolumeTag("0")
83
mTag := names.NewMachineTag("0")
85
s.attachmentParams = &storage.VolumeAttachmentParams{
86
AttachmentParams: storage.AttachmentParams{
91
VolumeId: s.BaseDisk.Name,
92
Volume: names.NewVolumeTag("0"),
94
s.params = []storage.VolumeParams{{
98
Attachment: s.attachmentParams,
103
func (s *volumeSourceSuite) TestCreateVolumesNoInstance(c *gc.C) {
104
res, err := s.source.CreateVolumes(s.params)
105
c.Check(err, jc.ErrorIsNil)
106
c.Check(res, gc.HasLen, 1)
107
expectedErr := "cannot obtain \"spam\" from instance cache: cannot attach to non-running instance spam"
108
c.Assert(res[0].Error, gc.ErrorMatches, expectedErr)
112
func (s *volumeSourceSuite) TestCreateVolumesNoDiskCreated(c *gc.C) {
113
s.FakeConn.Insts = []google.Instance{*s.BaseInstance}
114
res, err := s.source.CreateVolumes(s.params)
115
c.Check(err, jc.ErrorIsNil)
116
c.Check(res, gc.HasLen, 1)
117
c.Assert(res[0].Error, gc.ErrorMatches, "unexpected number of disks created: 0")
121
func (s *volumeSourceSuite) TestCreateVolumes(c *gc.C) {
122
s.FakeConn.Insts = []google.Instance{*s.BaseInstance}
123
s.FakeConn.GoogleDisks = []*google.Disk{s.BaseDisk}
124
s.FakeConn.GoogleDisk = s.BaseDisk
125
s.FakeConn.AttachedDisk = &google.AttachedDisk{
126
VolumeName: s.BaseDisk.Name,
127
DeviceName: "home-zone-1234567",
130
res, err := s.source.CreateVolumes(s.params)
131
c.Check(err, jc.ErrorIsNil)
132
c.Check(res, gc.HasLen, 1)
133
// Volume was created
134
c.Assert(res[0].Error, jc.ErrorIsNil)
135
c.Assert(res[0].Volume.VolumeId, gc.Equals, s.BaseDisk.Name)
136
c.Assert(res[0].Volume.HardwareId, gc.Equals, "")
138
// Volume was also attached as indicated by Attachment in params.
139
c.Assert(res[0].VolumeAttachment.DeviceName, gc.Equals, "")
140
c.Assert(res[0].VolumeAttachment.DeviceLink, gc.Equals, "/dev/disk/by-id/google-home-zone-1234567")
141
c.Assert(res[0].VolumeAttachment.Machine.String(), gc.Equals, "machine-0")
142
c.Assert(res[0].VolumeAttachment.ReadOnly, jc.IsFalse)
143
c.Assert(res[0].VolumeAttachment.Volume.String(), gc.Equals, "volume-0")
145
// Internals where properly called
147
createCalled, call := s.FakeConn.WasCalled("CreateDisks")
148
c.Check(call, gc.HasLen, 1)
149
c.Assert(createCalled, jc.IsTrue)
150
c.Assert(call[0].ZoneName, gc.Equals, "home-zone")
151
c.Assert(call[0].Disks[0].Name, jc.HasPrefix, "home-zone--")
153
// Instance existence Checking
154
instanceDisksCalled, call := s.FakeConn.WasCalled("InstanceDisks")
155
c.Check(call, gc.HasLen, 1)
156
c.Assert(instanceDisksCalled, jc.IsTrue)
157
c.Assert(call[0].ZoneName, gc.Equals, "home-zone")
158
c.Assert(call[0].InstanceId, gc.Equals, string(s.instId))
161
attachCalled, call := s.FakeConn.WasCalled("AttachDisk")
162
c.Check(call, gc.HasLen, 1)
163
c.Assert(attachCalled, jc.IsTrue)
164
c.Assert(call[0].ZoneName, gc.Equals, "home-zone")
165
c.Assert(call[0].VolumeName, jc.HasPrefix, "home-zone--")
166
c.Assert(call[0].InstanceId, gc.Equals, string(s.instId))
169
func (s *volumeSourceSuite) TestDestroyVolumes(c *gc.C) {
170
errs, err := s.source.DestroyVolumes([]string{"a--volume-name"})
171
c.Check(err, jc.ErrorIsNil)
172
c.Check(errs, gc.HasLen, 1)
173
c.Assert(errs[0], jc.ErrorIsNil)
175
destroyCalled, call := s.FakeConn.WasCalled("RemoveDisk")
176
c.Check(call, gc.HasLen, 1)
177
c.Assert(destroyCalled, jc.IsTrue)
178
c.Assert(call[0].ZoneName, gc.Equals, "a")
179
c.Assert(call[0].ID, gc.Equals, "a--volume-name")
182
func (s *volumeSourceSuite) TestListVolumes(c *gc.C) {
183
s.FakeConn.GoogleDisks = []*google.Disk{s.BaseDisk}
184
s.FakeConn.Zones = []google.AvailabilityZone{google.NewZone("home-zone", "Ready", "", "")}
185
vols, err := s.source.ListVolumes()
186
c.Check(err, jc.ErrorIsNil)
187
c.Assert(vols, gc.HasLen, 1)
189
azsCalled, call := s.FakeConn.WasCalled("AvailabilityZones")
190
c.Check(call, gc.HasLen, 1)
191
c.Assert(azsCalled, jc.IsTrue)
192
c.Assert(call[0].Region, gc.Equals, "")
194
disksCalled, call := s.FakeConn.WasCalled("Disks")
195
c.Check(call, gc.HasLen, 1)
196
c.Assert(disksCalled, jc.IsTrue)
197
c.Assert(call[0].ZoneName, gc.Equals, "home-zone")
200
func (s *volumeSourceSuite) TestListVolumesOnlyListsCurrentModelUUID(c *gc.C) {
201
otherDisk := &google.Disk{
203
Name: "home-zone--566fe7b2-c026-4a86-a2cc-84cb7f9a4868",
205
Status: google.StatusReady,
207
Description: "a-different-model-uuid",
209
s.FakeConn.GoogleDisks = []*google.Disk{s.BaseDisk, otherDisk}
210
s.FakeConn.Zones = []google.AvailabilityZone{google.NewZone("home-zone", "Ready", "", "")}
211
vols, err := s.source.ListVolumes()
212
c.Check(err, jc.ErrorIsNil)
213
c.Assert(vols, gc.HasLen, 1)
216
func (s *volumeSourceSuite) TestListVolumesListsEmptyUUIDVolumes(c *gc.C) {
217
otherDisk := &google.Disk{
219
Name: "home-zone--566fe7b2-c026-4a86-a2cc-84cb7f9a4868",
221
Status: google.StatusReady,
225
s.FakeConn.GoogleDisks = []*google.Disk{s.BaseDisk, otherDisk}
226
s.FakeConn.Zones = []google.AvailabilityZone{google.NewZone("home-zone", "Ready", "", "")}
227
vols, err := s.source.ListVolumes()
228
c.Check(err, jc.ErrorIsNil)
229
c.Assert(vols, gc.HasLen, 2)
232
func (s *volumeSourceSuite) TestListVolumesIgnoresNamesFormatteDifferently(c *gc.C) {
233
otherDisk := &google.Disk{
235
Name: "juju-566fe7b2-c026-4a86-a2cc-84cb7f9a4868",
237
Status: google.StatusReady,
241
s.FakeConn.GoogleDisks = []*google.Disk{s.BaseDisk, otherDisk}
242
s.FakeConn.Zones = []google.AvailabilityZone{google.NewZone("home-zone", "Ready", "", "")}
243
vols, err := s.source.ListVolumes()
244
c.Check(err, jc.ErrorIsNil)
245
c.Assert(vols, gc.HasLen, 1)
248
func (s *volumeSourceSuite) TestDescribeVolumes(c *gc.C) {
249
s.FakeConn.GoogleDisk = s.BaseDisk
250
volName := "home-zone--c930380d-8337-4bf5-b07a-9dbb5ae771e4"
251
res, err := s.source.DescribeVolumes([]string{volName})
252
c.Check(err, jc.ErrorIsNil)
253
c.Assert(res, gc.HasLen, 1)
254
c.Assert(res[0].VolumeInfo.Size, gc.Equals, uint64(1024))
255
c.Assert(res[0].VolumeInfo.VolumeId, gc.Equals, volName)
257
diskCalled, call := s.FakeConn.WasCalled("Disk")
258
c.Check(call, gc.HasLen, 1)
259
c.Assert(diskCalled, jc.IsTrue)
260
c.Assert(call[0].ZoneName, gc.Equals, "home-zone")
261
c.Assert(call[0].ID, gc.Equals, volName)
264
func (s *volumeSourceSuite) TestAttachVolumes(c *gc.C) {
265
volName := "home-zone--c930380d-8337-4bf5-b07a-9dbb5ae771e4"
266
attachments := []storage.VolumeAttachmentParams{*s.attachmentParams}
267
s.FakeConn.AttachedDisk = &google.AttachedDisk{
268
VolumeName: s.BaseDisk.Name,
269
DeviceName: "home-zone-1234567",
272
res, err := s.source.AttachVolumes(attachments)
273
c.Check(err, jc.ErrorIsNil)
274
c.Assert(res, gc.HasLen, 1)
275
c.Assert(res[0].VolumeAttachment.Volume.String(), gc.Equals, "volume-0")
276
c.Assert(res[0].VolumeAttachment.Machine.String(), gc.Equals, "machine-0")
277
c.Assert(res[0].VolumeAttachment.VolumeAttachmentInfo.DeviceName, gc.Equals, "home-zone-1234567")
280
attachCalled, call := s.FakeConn.WasCalled("AttachDisk")
281
c.Check(call, gc.HasLen, 1)
282
c.Assert(attachCalled, jc.IsTrue)
283
c.Assert(call[0].ZoneName, gc.Equals, "home-zone")
284
c.Assert(call[0].VolumeName, gc.Equals, volName)
285
c.Assert(call[0].InstanceId, gc.Equals, string(s.instId))
289
func (s *volumeSourceSuite) TestDetachVolumes(c *gc.C) {
290
volName := "home-zone--c930380d-8337-4bf5-b07a-9dbb5ae771e4"
291
attachments := []storage.VolumeAttachmentParams{*s.attachmentParams}
292
errs, err := s.source.DetachVolumes(attachments)
293
c.Check(err, jc.ErrorIsNil)
294
c.Assert(errs, gc.HasLen, 1)
295
c.Assert(errs[0], jc.ErrorIsNil)
298
attachCalled, call := s.FakeConn.WasCalled("DetachDisk")
299
c.Check(call, gc.HasLen, 1)
300
c.Assert(attachCalled, jc.IsTrue)
301
c.Assert(call[0].ZoneName, gc.Equals, "home-zone")
302
c.Assert(call[0].InstanceId, gc.Equals, string(s.instId))
303
c.Assert(call[0].VolumeName, gc.Equals, volName)