~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/provider/openstack/cinder_test.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2015 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package openstack_test
 
5
 
 
6
import (
 
7
        "fmt"
 
8
        "time"
 
9
 
 
10
        "github.com/juju/errors"
 
11
        gitjujutesting "github.com/juju/testing"
 
12
        jc "github.com/juju/testing/checkers"
 
13
        "github.com/juju/utils"
 
14
        gc "gopkg.in/check.v1"
 
15
        "gopkg.in/goose.v1/cinder"
 
16
        "gopkg.in/goose.v1/identity"
 
17
        "gopkg.in/goose.v1/nova"
 
18
        "gopkg.in/juju/names.v2"
 
19
 
 
20
        "github.com/juju/juju/environs/tags"
 
21
        "github.com/juju/juju/instance"
 
22
        "github.com/juju/juju/provider/openstack"
 
23
        "github.com/juju/juju/storage"
 
24
        "github.com/juju/juju/testing"
 
25
)
 
26
 
 
27
const (
 
28
        mockVolId    = "0"
 
29
        mockVolSize  = 1024 * 2
 
30
        mockVolName  = "123"
 
31
        mockServerId = "mock-server-id"
 
32
        mockVolJson  = `{"volume":{"id": "` + mockVolId + `", "size":1,"name":"` + mockVolName + `"}}`
 
33
)
 
34
 
 
35
var (
 
36
        mockVolumeTag  = names.NewVolumeTag(mockVolName)
 
37
        mockMachineTag = names.NewMachineTag("456")
 
38
)
 
39
 
 
40
var _ = gc.Suite(&cinderVolumeSourceSuite{})
 
41
 
 
42
type cinderVolumeSourceSuite struct {
 
43
        testing.BaseSuite
 
44
}
 
45
 
 
46
func init() {
 
47
        // Override attempt strategy to speed things up.
 
48
        openstack.CinderAttempt.Delay = 0
 
49
}
 
50
 
 
51
func (s *cinderVolumeSourceSuite) TestAttachVolumes(c *gc.C) {
 
52
        mockAdapter := &mockAdapter{
 
53
                attachVolume: func(serverId, volId, mountPoint string) (*nova.VolumeAttachment, error) {
 
54
                        c.Check(volId, gc.Equals, mockVolId)
 
55
                        c.Check(serverId, gc.Equals, mockServerId)
 
56
                        return &nova.VolumeAttachment{
 
57
                                Id:       volId,
 
58
                                VolumeId: volId,
 
59
                                ServerId: serverId,
 
60
                                Device:   "/dev/sda",
 
61
                        }, nil
 
62
                },
 
63
        }
 
64
 
 
65
        volSource := openstack.NewCinderVolumeSource(mockAdapter)
 
66
        results, err := volSource.AttachVolumes([]storage.VolumeAttachmentParams{{
 
67
                Volume:   mockVolumeTag,
 
68
                VolumeId: mockVolId,
 
69
                AttachmentParams: storage.AttachmentParams{
 
70
                        Provider:   openstack.CinderProviderType,
 
71
                        Machine:    mockMachineTag,
 
72
                        InstanceId: instance.Id(mockServerId),
 
73
                }},
 
74
        })
 
75
        c.Assert(err, jc.ErrorIsNil)
 
76
        c.Check(results, jc.DeepEquals, []storage.AttachVolumesResult{{
 
77
                VolumeAttachment: &storage.VolumeAttachment{
 
78
                        mockVolumeTag,
 
79
                        mockMachineTag,
 
80
                        storage.VolumeAttachmentInfo{
 
81
                                DeviceName: "sda",
 
82
                        },
 
83
                },
 
84
        }})
 
85
}
 
86
 
 
87
func (s *cinderVolumeSourceSuite) TestCreateVolume(c *gc.C) {
 
88
        const (
 
89
                requestedSize = 2 * 1024
 
90
                providedSize  = 3 * 1024
 
91
        )
 
92
 
 
93
        s.PatchValue(openstack.CinderAttempt, utils.AttemptStrategy{Min: 3})
 
94
 
 
95
        var getVolumeCalls int
 
96
        mockAdapter := &mockAdapter{
 
97
                createVolume: func(args cinder.CreateVolumeVolumeParams) (*cinder.Volume, error) {
 
98
                        c.Assert(args, jc.DeepEquals, cinder.CreateVolumeVolumeParams{
 
99
                                Size: requestedSize / 1024,
 
100
                                Name: "juju-testenv-volume-123",
 
101
                        })
 
102
                        return &cinder.Volume{
 
103
                                ID: mockVolId,
 
104
                        }, nil
 
105
                },
 
106
                getVolume: func(volumeId string) (*cinder.Volume, error) {
 
107
                        var status string
 
108
                        getVolumeCalls++
 
109
                        if getVolumeCalls > 1 {
 
110
                                status = "available"
 
111
                        }
 
112
                        return &cinder.Volume{
 
113
                                ID:     volumeId,
 
114
                                Size:   providedSize / 1024,
 
115
                                Status: status,
 
116
                        }, nil
 
117
                },
 
118
                attachVolume: func(serverId, volId, mountPoint string) (*nova.VolumeAttachment, error) {
 
119
                        c.Check(volId, gc.Equals, mockVolId)
 
120
                        c.Check(serverId, gc.Equals, mockServerId)
 
121
                        return &nova.VolumeAttachment{
 
122
                                Id:       volId,
 
123
                                VolumeId: volId,
 
124
                                ServerId: serverId,
 
125
                                Device:   "/dev/sda",
 
126
                        }, nil
 
127
                },
 
128
        }
 
129
 
 
130
        volSource := openstack.NewCinderVolumeSource(mockAdapter)
 
131
        results, err := volSource.CreateVolumes([]storage.VolumeParams{{
 
132
                Provider: openstack.CinderProviderType,
 
133
                Tag:      mockVolumeTag,
 
134
                Size:     requestedSize,
 
135
                Attachment: &storage.VolumeAttachmentParams{
 
136
                        AttachmentParams: storage.AttachmentParams{
 
137
                                Provider:   openstack.CinderProviderType,
 
138
                                Machine:    mockMachineTag,
 
139
                                InstanceId: instance.Id(mockServerId),
 
140
                        },
 
141
                },
 
142
        }})
 
143
        c.Assert(err, jc.ErrorIsNil)
 
144
        c.Assert(results, gc.HasLen, 1)
 
145
        c.Assert(results[0].Error, jc.ErrorIsNil)
 
146
 
 
147
        c.Check(results[0].Volume, jc.DeepEquals, &storage.Volume{
 
148
                mockVolumeTag,
 
149
                storage.VolumeInfo{
 
150
                        VolumeId:   mockVolId,
 
151
                        Size:       providedSize,
 
152
                        Persistent: true,
 
153
                },
 
154
        })
 
155
 
 
156
        // should have been 2 calls to GetVolume: twice initially
 
157
        // to wait until the volume became available.
 
158
        c.Check(getVolumeCalls, gc.Equals, 2)
 
159
}
 
160
 
 
161
func (s *cinderVolumeSourceSuite) TestResourceTags(c *gc.C) {
 
162
        var created bool
 
163
        mockAdapter := &mockAdapter{
 
164
                createVolume: func(args cinder.CreateVolumeVolumeParams) (*cinder.Volume, error) {
 
165
                        created = true
 
166
                        c.Assert(args, jc.DeepEquals, cinder.CreateVolumeVolumeParams{
 
167
                                Size: 1,
 
168
                                Name: "juju-testenv-volume-123",
 
169
                                Metadata: map[string]string{
 
170
                                        "ResourceTag1": "Value1",
 
171
                                        "ResourceTag2": "Value2",
 
172
                                },
 
173
                        })
 
174
                        return &cinder.Volume{ID: mockVolId}, nil
 
175
                },
 
176
                getVolume: func(volumeId string) (*cinder.Volume, error) {
 
177
                        return &cinder.Volume{
 
178
                                ID:     volumeId,
 
179
                                Size:   1,
 
180
                                Status: "available",
 
181
                        }, nil
 
182
                },
 
183
                attachVolume: func(serverId, volId, mountPoint string) (*nova.VolumeAttachment, error) {
 
184
                        return &nova.VolumeAttachment{
 
185
                                Id:       volId,
 
186
                                VolumeId: volId,
 
187
                                ServerId: serverId,
 
188
                                Device:   "/dev/sda",
 
189
                        }, nil
 
190
                },
 
191
        }
 
192
 
 
193
        volSource := openstack.NewCinderVolumeSource(mockAdapter)
 
194
        _, err := volSource.CreateVolumes([]storage.VolumeParams{{
 
195
                Provider: openstack.CinderProviderType,
 
196
                Tag:      mockVolumeTag,
 
197
                Size:     1024,
 
198
                ResourceTags: map[string]string{
 
199
                        "ResourceTag1": "Value1",
 
200
                        "ResourceTag2": "Value2",
 
201
                },
 
202
                Attachment: &storage.VolumeAttachmentParams{
 
203
                        AttachmentParams: storage.AttachmentParams{
 
204
                                Provider:   openstack.CinderProviderType,
 
205
                                Machine:    mockMachineTag,
 
206
                                InstanceId: instance.Id(mockServerId),
 
207
                        },
 
208
                },
 
209
        }})
 
210
        c.Assert(err, jc.ErrorIsNil)
 
211
        c.Assert(created, jc.IsTrue)
 
212
}
 
213
 
 
214
func (s *cinderVolumeSourceSuite) TestListVolumes(c *gc.C) {
 
215
        mockAdapter := &mockAdapter{
 
216
                getVolumesDetail: func() ([]cinder.Volume, error) {
 
217
                        return []cinder.Volume{{
 
218
                                ID: "volume-1",
 
219
                        }, {
 
220
                                ID: "volume-2",
 
221
                                Metadata: map[string]string{
 
222
                                        tags.JujuModel: "something-else",
 
223
                                },
 
224
                        }, {
 
225
                                ID: "volume-3",
 
226
                                Metadata: map[string]string{
 
227
                                        tags.JujuModel: testing.ModelTag.Id(),
 
228
                                },
 
229
                        }}, nil
 
230
                },
 
231
        }
 
232
        volSource := openstack.NewCinderVolumeSource(mockAdapter)
 
233
        volumeIds, err := volSource.ListVolumes()
 
234
        c.Assert(err, jc.ErrorIsNil)
 
235
        c.Check(volumeIds, jc.DeepEquals, []string{"volume-3"})
 
236
}
 
237
 
 
238
func (s *cinderVolumeSourceSuite) TestDescribeVolumes(c *gc.C) {
 
239
        mockAdapter := &mockAdapter{
 
240
                getVolumesDetail: func() ([]cinder.Volume, error) {
 
241
                        return []cinder.Volume{{
 
242
                                ID:   mockVolId,
 
243
                                Size: mockVolSize / 1024,
 
244
                        }}, nil
 
245
                },
 
246
        }
 
247
        volSource := openstack.NewCinderVolumeSource(mockAdapter)
 
248
        volumes, err := volSource.DescribeVolumes([]string{mockVolId})
 
249
        c.Assert(err, jc.ErrorIsNil)
 
250
        c.Check(volumes, jc.DeepEquals, []storage.DescribeVolumesResult{{
 
251
                VolumeInfo: &storage.VolumeInfo{
 
252
                        VolumeId:   mockVolId,
 
253
                        Size:       mockVolSize,
 
254
                        Persistent: true,
 
255
                },
 
256
        }})
 
257
}
 
258
 
 
259
func (s *cinderVolumeSourceSuite) TestDestroyVolumes(c *gc.C) {
 
260
        mockAdapter := &mockAdapter{}
 
261
        volSource := openstack.NewCinderVolumeSource(mockAdapter)
 
262
        errs, err := volSource.DestroyVolumes([]string{mockVolId})
 
263
        c.Assert(err, jc.ErrorIsNil)
 
264
        c.Assert(errs, jc.DeepEquals, []error{nil})
 
265
        mockAdapter.CheckCalls(c, []gitjujutesting.StubCall{
 
266
                {"GetVolume", []interface{}{mockVolId}},
 
267
                {"DeleteVolume", []interface{}{mockVolId}},
 
268
        })
 
269
}
 
270
 
 
271
func (s *cinderVolumeSourceSuite) TestDestroyVolumesAttached(c *gc.C) {
 
272
        statuses := []string{"in-use", "detaching", "available"}
 
273
 
 
274
        mockAdapter := &mockAdapter{
 
275
                getVolume: func(volId string) (*cinder.Volume, error) {
 
276
                        c.Assert(statuses, gc.Not(gc.HasLen), 0)
 
277
                        status := statuses[0]
 
278
                        statuses = statuses[1:]
 
279
                        return &cinder.Volume{
 
280
                                ID:     volId,
 
281
                                Status: status,
 
282
                        }, nil
 
283
                },
 
284
        }
 
285
 
 
286
        volSource := openstack.NewCinderVolumeSource(mockAdapter)
 
287
        errs, err := volSource.DestroyVolumes([]string{mockVolId})
 
288
        c.Assert(err, jc.ErrorIsNil)
 
289
        c.Assert(errs, gc.HasLen, 1)
 
290
        c.Assert(errs[0], jc.ErrorIsNil)
 
291
        c.Assert(statuses, gc.HasLen, 0)
 
292
        mockAdapter.CheckCalls(c, []gitjujutesting.StubCall{{
 
293
                "GetVolume", []interface{}{mockVolId},
 
294
        }, {
 
295
                "GetVolume", []interface{}{mockVolId},
 
296
        }, {
 
297
                "GetVolume", []interface{}{mockVolId},
 
298
        }, {
 
299
                "DeleteVolume", []interface{}{mockVolId},
 
300
        }})
 
301
}
 
302
 
 
303
func (s *cinderVolumeSourceSuite) TestDetachVolumes(c *gc.C) {
 
304
        const mockServerId2 = mockServerId + "2"
 
305
 
 
306
        var numListCalls, numDetachCalls int
 
307
        mockAdapter := &mockAdapter{
 
308
                listVolumeAttachments: func(serverId string) ([]nova.VolumeAttachment, error) {
 
309
                        numListCalls++
 
310
                        if serverId == mockServerId2 {
 
311
                                // no attachments
 
312
                                return nil, nil
 
313
                        }
 
314
                        c.Check(serverId, gc.Equals, mockServerId)
 
315
                        return []nova.VolumeAttachment{{
 
316
                                Id:       mockVolId,
 
317
                                VolumeId: mockVolId,
 
318
                                ServerId: mockServerId,
 
319
                                Device:   "/dev/sda",
 
320
                        }}, nil
 
321
                },
 
322
                detachVolume: func(serverId, volId string) error {
 
323
                        numDetachCalls++
 
324
                        c.Check(serverId, gc.Equals, mockServerId)
 
325
                        c.Check(volId, gc.Equals, mockVolId)
 
326
                        return nil
 
327
                },
 
328
        }
 
329
 
 
330
        volSource := openstack.NewCinderVolumeSource(mockAdapter)
 
331
        errs, err := volSource.DetachVolumes([]storage.VolumeAttachmentParams{{
 
332
                Volume:   names.NewVolumeTag("123"),
 
333
                VolumeId: mockVolId,
 
334
                AttachmentParams: storage.AttachmentParams{
 
335
                        Machine:    names.NewMachineTag("0"),
 
336
                        InstanceId: mockServerId,
 
337
                },
 
338
        }, {
 
339
                Volume:   names.NewVolumeTag("42"),
 
340
                VolumeId: "42",
 
341
                AttachmentParams: storage.AttachmentParams{
 
342
                        Machine:    names.NewMachineTag("0"),
 
343
                        InstanceId: mockServerId2,
 
344
                },
 
345
        }})
 
346
        c.Assert(err, jc.ErrorIsNil)
 
347
        c.Assert(errs, jc.DeepEquals, []error{nil, nil})
 
348
        // DetachVolume should only be called for existing attachments.
 
349
        mockAdapter.CheckCalls(c, []gitjujutesting.StubCall{{
 
350
                "ListVolumeAttachments", []interface{}{mockServerId},
 
351
        }, {
 
352
                "DetachVolume", []interface{}{mockServerId, mockVolId},
 
353
        }, {
 
354
                "ListVolumeAttachments", []interface{}{mockServerId2},
 
355
        }})
 
356
}
 
357
 
 
358
func (s *cinderVolumeSourceSuite) TestCreateVolumeCleanupDestroys(c *gc.C) {
 
359
        var numCreateCalls, numDestroyCalls, numGetCalls int
 
360
        mockAdapter := &mockAdapter{
 
361
                createVolume: func(args cinder.CreateVolumeVolumeParams) (*cinder.Volume, error) {
 
362
                        numCreateCalls++
 
363
                        if numCreateCalls == 3 {
 
364
                                return nil, errors.New("no volume for you")
 
365
                        }
 
366
                        return &cinder.Volume{
 
367
                                ID:     fmt.Sprint(numCreateCalls),
 
368
                                Status: "",
 
369
                        }, nil
 
370
                },
 
371
                deleteVolume: func(volId string) error {
 
372
                        numDestroyCalls++
 
373
                        c.Assert(volId, gc.Equals, "2")
 
374
                        return errors.New("destroy fails")
 
375
                },
 
376
                getVolume: func(volumeId string) (*cinder.Volume, error) {
 
377
                        numGetCalls++
 
378
                        if numGetCalls == 2 {
 
379
                                return nil, errors.New("no volume details for you")
 
380
                        }
 
381
                        return &cinder.Volume{
 
382
                                ID:     "4",
 
383
                                Size:   mockVolSize / 1024,
 
384
                                Status: "available",
 
385
                        }, nil
 
386
                },
 
387
        }
 
388
 
 
389
        volSource := openstack.NewCinderVolumeSource(mockAdapter)
 
390
        volumeParams := []storage.VolumeParams{{
 
391
                Provider: openstack.CinderProviderType,
 
392
                Tag:      names.NewVolumeTag("0"),
 
393
                Size:     mockVolSize,
 
394
                Attachment: &storage.VolumeAttachmentParams{
 
395
                        AttachmentParams: storage.AttachmentParams{
 
396
                                Provider:   openstack.CinderProviderType,
 
397
                                Machine:    mockMachineTag,
 
398
                                InstanceId: instance.Id(mockServerId),
 
399
                        },
 
400
                },
 
401
        }, {
 
402
                Provider: openstack.CinderProviderType,
 
403
                Tag:      names.NewVolumeTag("1"),
 
404
                Size:     mockVolSize,
 
405
                Attachment: &storage.VolumeAttachmentParams{
 
406
                        AttachmentParams: storage.AttachmentParams{
 
407
                                Provider:   openstack.CinderProviderType,
 
408
                                Machine:    mockMachineTag,
 
409
                                InstanceId: instance.Id(mockServerId),
 
410
                        },
 
411
                },
 
412
        }, {
 
413
                Provider: openstack.CinderProviderType,
 
414
                Tag:      names.NewVolumeTag("2"),
 
415
                Size:     mockVolSize,
 
416
                Attachment: &storage.VolumeAttachmentParams{
 
417
                        AttachmentParams: storage.AttachmentParams{
 
418
                                Provider:   openstack.CinderProviderType,
 
419
                                Machine:    mockMachineTag,
 
420
                                InstanceId: instance.Id(mockServerId),
 
421
                        },
 
422
                },
 
423
        }}
 
424
        results, err := volSource.CreateVolumes(volumeParams)
 
425
        c.Assert(err, jc.ErrorIsNil)
 
426
        c.Assert(results, gc.HasLen, 3)
 
427
        c.Assert(results[0].Error, jc.ErrorIsNil)
 
428
        c.Assert(results[1].Error, gc.ErrorMatches, "waiting for volume to be provisioned: getting volume: no volume details for you")
 
429
        c.Assert(results[2].Error, gc.ErrorMatches, "no volume for you")
 
430
        c.Assert(numCreateCalls, gc.Equals, 3)
 
431
        c.Assert(numGetCalls, gc.Equals, 2)
 
432
        c.Assert(numDestroyCalls, gc.Equals, 1)
 
433
}
 
434
 
 
435
type mockAdapter struct {
 
436
        gitjujutesting.Stub
 
437
        getVolume             func(string) (*cinder.Volume, error)
 
438
        getVolumesDetail      func() ([]cinder.Volume, error)
 
439
        deleteVolume          func(string) error
 
440
        createVolume          func(cinder.CreateVolumeVolumeParams) (*cinder.Volume, error)
 
441
        attachVolume          func(string, string, string) (*nova.VolumeAttachment, error)
 
442
        volumeStatusNotifier  func(string, string, int, time.Duration) <-chan error
 
443
        detachVolume          func(string, string) error
 
444
        listVolumeAttachments func(string) ([]nova.VolumeAttachment, error)
 
445
}
 
446
 
 
447
func (ma *mockAdapter) GetVolume(volumeId string) (*cinder.Volume, error) {
 
448
        ma.MethodCall(ma, "GetVolume", volumeId)
 
449
        if ma.getVolume != nil {
 
450
                return ma.getVolume(volumeId)
 
451
        }
 
452
        return &cinder.Volume{
 
453
                ID:     volumeId,
 
454
                Status: "available",
 
455
        }, nil
 
456
}
 
457
 
 
458
func (ma *mockAdapter) GetVolumesDetail() ([]cinder.Volume, error) {
 
459
        ma.MethodCall(ma, "GetVolumesDetail")
 
460
        if ma.getVolumesDetail != nil {
 
461
                return ma.getVolumesDetail()
 
462
        }
 
463
        return nil, nil
 
464
}
 
465
 
 
466
func (ma *mockAdapter) DeleteVolume(volId string) error {
 
467
        ma.MethodCall(ma, "DeleteVolume", volId)
 
468
        if ma.deleteVolume != nil {
 
469
                return ma.deleteVolume(volId)
 
470
        }
 
471
        return nil
 
472
}
 
473
 
 
474
func (ma *mockAdapter) CreateVolume(args cinder.CreateVolumeVolumeParams) (*cinder.Volume, error) {
 
475
        ma.MethodCall(ma, "CreateVolume", args)
 
476
        if ma.createVolume != nil {
 
477
                return ma.createVolume(args)
 
478
        }
 
479
        return nil, errors.NotImplementedf("CreateVolume")
 
480
}
 
481
 
 
482
func (ma *mockAdapter) AttachVolume(serverId, volumeId, mountPoint string) (*nova.VolumeAttachment, error) {
 
483
        ma.MethodCall(ma, "AttachVolume", serverId, volumeId, mountPoint)
 
484
        if ma.attachVolume != nil {
 
485
                return ma.attachVolume(serverId, volumeId, mountPoint)
 
486
        }
 
487
        return nil, errors.NotImplementedf("AttachVolume")
 
488
}
 
489
 
 
490
func (ma *mockAdapter) DetachVolume(serverId, attachmentId string) error {
 
491
        ma.MethodCall(ma, "DetachVolume", serverId, attachmentId)
 
492
        if ma.detachVolume != nil {
 
493
                return ma.detachVolume(serverId, attachmentId)
 
494
        }
 
495
        return nil
 
496
}
 
497
 
 
498
func (ma *mockAdapter) ListVolumeAttachments(serverId string) ([]nova.VolumeAttachment, error) {
 
499
        ma.MethodCall(ma, "ListVolumeAttachments", serverId)
 
500
        if ma.listVolumeAttachments != nil {
 
501
                return ma.listVolumeAttachments(serverId)
 
502
        }
 
503
        return nil, nil
 
504
}
 
505
 
 
506
type testEndpointResolver struct {
 
507
        regionEndpoints map[string]identity.ServiceURLs
 
508
}
 
509
 
 
510
func (r testEndpointResolver) EndpointsForRegion(region string) identity.ServiceURLs {
 
511
        return r.regionEndpoints[region]
 
512
}
 
513
 
 
514
func (s *cinderVolumeSourceSuite) TestGetVolumeEndpointVolume(c *gc.C) {
 
515
        client := testEndpointResolver{regionEndpoints: map[string]identity.ServiceURLs{
 
516
                "west": map[string]string{"volume": "http://cinder.testing/v1"},
 
517
        }}
 
518
        url, err := openstack.GetVolumeEndpointURL(client, "west")
 
519
        c.Assert(err, jc.ErrorIsNil)
 
520
        c.Assert(url.String(), gc.Equals, "http://cinder.testing/v1")
 
521
}
 
522
 
 
523
func (s *cinderVolumeSourceSuite) TestGetVolumeEndpointVolumeV2(c *gc.C) {
 
524
        client := testEndpointResolver{regionEndpoints: map[string]identity.ServiceURLs{
 
525
                "west": map[string]string{"volumev2": "http://cinder.testing/v2"},
 
526
        }}
 
527
        url, err := openstack.GetVolumeEndpointURL(client, "west")
 
528
        c.Assert(err, jc.ErrorIsNil)
 
529
        c.Assert(url.String(), gc.Equals, "http://cinder.testing/v2")
 
530
}
 
531
 
 
532
func (s *cinderVolumeSourceSuite) TestGetVolumeEndpointPreferV2(c *gc.C) {
 
533
        client := testEndpointResolver{regionEndpoints: map[string]identity.ServiceURLs{
 
534
                "south": map[string]string{
 
535
                        "volume":   "http://cinder.testing/v1",
 
536
                        "volumev2": "http://cinder.testing/v2",
 
537
                },
 
538
        }}
 
539
        url, err := openstack.GetVolumeEndpointURL(client, "south")
 
540
        c.Assert(err, jc.ErrorIsNil)
 
541
        c.Assert(url.String(), gc.Equals, "http://cinder.testing/v2")
 
542
}
 
543
 
 
544
func (s *cinderVolumeSourceSuite) TestGetVolumeEndpointMissing(c *gc.C) {
 
545
        client := testEndpointResolver{}
 
546
        url, err := openstack.GetVolumeEndpointURL(client, "east")
 
547
        c.Assert(err, gc.ErrorMatches, `endpoint "volume" in region "east" not found`)
 
548
        c.Assert(err, jc.Satisfies, errors.IsNotFound)
 
549
        c.Assert(url, gc.IsNil)
 
550
}
 
551
 
 
552
func (s *cinderVolumeSourceSuite) TestGetVolumeEndpointBadURL(c *gc.C) {
 
553
        client := testEndpointResolver{regionEndpoints: map[string]identity.ServiceURLs{
 
554
                "north": map[string]string{"volumev2": "some %4"},
 
555
        }}
 
556
        url, err := openstack.GetVolumeEndpointURL(client, "north")
 
557
        c.Assert(err, gc.ErrorMatches, `parse some %4: .*`)
 
558
        c.Assert(url, gc.IsNil)
 
559
}