~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/provider/gce/testing_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 2014 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package gce
 
5
 
 
6
import (
 
7
        "fmt"
 
8
        "strings"
 
9
 
 
10
        gitjujutesting "github.com/juju/testing"
 
11
        jc "github.com/juju/testing/checkers"
 
12
        "github.com/juju/utils/arch"
 
13
        "github.com/juju/version"
 
14
        gc "gopkg.in/check.v1"
 
15
 
 
16
        "github.com/juju/juju/cloud"
 
17
        "github.com/juju/juju/cloudconfig/instancecfg"
 
18
        "github.com/juju/juju/cloudconfig/providerinit"
 
19
        "github.com/juju/juju/constraints"
 
20
        "github.com/juju/juju/environs"
 
21
        "github.com/juju/juju/environs/config"
 
22
        "github.com/juju/juju/environs/imagemetadata"
 
23
        "github.com/juju/juju/environs/instances"
 
24
        "github.com/juju/juju/environs/simplestreams"
 
25
        "github.com/juju/juju/environs/tags"
 
26
        "github.com/juju/juju/instance"
 
27
        "github.com/juju/juju/network"
 
28
        "github.com/juju/juju/provider/common"
 
29
        "github.com/juju/juju/provider/gce/google"
 
30
        "github.com/juju/juju/testing"
 
31
        coretools "github.com/juju/juju/tools"
 
32
)
 
33
 
 
34
// These values are fake GCE auth credentials for use in tests.
 
35
const (
 
36
        ClientName  = "ba9876543210-0123456789abcdefghijklmnopqrstuv"
 
37
        ClientID    = ClientName + ".apps.googleusercontent.com"
 
38
        ClientEmail = ClientName + "@developer.gserviceaccount.com"
 
39
        ProjectID   = "my-juju"
 
40
        PrivateKey  = `-----BEGIN PRIVATE KEY-----
 
41
...
 
42
...
 
43
...
 
44
...
 
45
...
 
46
...
 
47
...
 
48
...
 
49
...
 
50
...
 
51
...
 
52
...
 
53
...
 
54
...
 
55
-----END PRIVATE KEY-----
 
56
`
 
57
)
 
58
 
 
59
// These are fake config values for use in tests.
 
60
var (
 
61
        AuthFile = fmt.Sprintf(`{
 
62
  "private_key_id": "abcdef0123456789abcdef0123456789abcdef01",
 
63
  "private_key": "%s",
 
64
  "client_email": "%s",
 
65
  "client_id": "%s",
 
66
  "type": "service_account"
 
67
}`, strings.Replace(PrivateKey, "\n", "\\n", -1), ClientEmail, ClientID)
 
68
 
 
69
        ConfigAttrs = testing.FakeConfig().Merge(testing.Attrs{
 
70
                "type":            "gce",
 
71
                "uuid":            "2d02eeac-9dbb-11e4-89d3-123b93f75cba",
 
72
                "controller-uuid": "bfef02f1-932a-425a-a102-62175dcabd1d",
 
73
        })
 
74
)
 
75
 
 
76
func MakeTestCloudSpec() environs.CloudSpec {
 
77
        cred := MakeTestCredential()
 
78
        return environs.CloudSpec{
 
79
                Type:       "gce",
 
80
                Name:       "google",
 
81
                Region:     "us-east1",
 
82
                Endpoint:   "https://www.googleapis.com",
 
83
                Credential: &cred,
 
84
        }
 
85
}
 
86
 
 
87
func MakeTestCredential() cloud.Credential {
 
88
        return cloud.NewCredential(
 
89
                cloud.OAuth2AuthType,
 
90
                map[string]string{
 
91
                        "project-id":   ProjectID,
 
92
                        "client-id":    ClientID,
 
93
                        "client-email": ClientEmail,
 
94
                        "private-key":  PrivateKey,
 
95
                },
 
96
        )
 
97
}
 
98
 
 
99
type BaseSuiteUnpatched struct {
 
100
        gitjujutesting.IsolationSuite
 
101
 
 
102
        ControllerUUID string
 
103
        Config         *config.Config
 
104
        EnvConfig      *environConfig
 
105
        Env            *environ
 
106
 
 
107
        Addresses       []network.Address
 
108
        BaseInstance    *google.Instance
 
109
        BaseDisk        *google.Disk
 
110
        Instance        *environInstance
 
111
        InstName        string
 
112
        UbuntuMetadata  map[string]string
 
113
        WindowsMetadata map[string]string
 
114
        StartInstArgs   environs.StartInstanceParams
 
115
        InstanceType    instances.InstanceType
 
116
 
 
117
        Ports []network.PortRange
 
118
}
 
119
 
 
120
var _ environs.Environ = (*environ)(nil)
 
121
var _ simplestreams.HasRegion = (*environ)(nil)
 
122
var _ instance.Instance = (*environInstance)(nil)
 
123
 
 
124
func (s *BaseSuiteUnpatched) SetUpTest(c *gc.C) {
 
125
        s.IsolationSuite.SetUpTest(c)
 
126
 
 
127
        s.ControllerUUID = testing.FakeControllerConfig().ControllerUUID()
 
128
        s.initEnv(c)
 
129
        s.initInst(c)
 
130
        s.initNet(c)
 
131
}
 
132
 
 
133
func (s *BaseSuiteUnpatched) Prefix() string {
 
134
        return s.Env.namespace.Prefix()
 
135
}
 
136
 
 
137
func (s *BaseSuiteUnpatched) initEnv(c *gc.C) {
 
138
        s.Env = &environ{
 
139
                name:  "google",
 
140
                cloud: MakeTestCloudSpec(),
 
141
        }
 
142
        cfg := s.NewConfig(c, nil)
 
143
        s.setConfig(c, cfg)
 
144
}
 
145
 
 
146
func (s *BaseSuiteUnpatched) initInst(c *gc.C) {
 
147
        tools := []*coretools.Tools{{
 
148
                Version: version.Binary{Arch: arch.AMD64, Series: "trusty"},
 
149
                URL:     "https://example.org",
 
150
        }}
 
151
 
 
152
        cons := constraints.Value{InstanceType: &allInstanceTypes[0].Name}
 
153
 
 
154
        instanceConfig, err := instancecfg.NewBootstrapInstanceConfig(testing.FakeControllerConfig(), cons, cons, "trusty", "")
 
155
        c.Assert(err, jc.ErrorIsNil)
 
156
 
 
157
        err = instanceConfig.SetTools(coretools.List(tools))
 
158
        c.Assert(err, jc.ErrorIsNil)
 
159
        instanceConfig.AuthorizedKeys = s.Config.AuthorizedKeys()
 
160
 
 
161
        userData, err := providerinit.ComposeUserData(instanceConfig, nil, GCERenderer{})
 
162
        c.Assert(err, jc.ErrorIsNil)
 
163
 
 
164
        authKeys, err := google.FormatAuthorizedKeys(instanceConfig.AuthorizedKeys, "ubuntu")
 
165
        c.Assert(err, jc.ErrorIsNil)
 
166
 
 
167
        s.UbuntuMetadata = map[string]string{
 
168
                tags.JujuIsController: "true",
 
169
                tags.JujuController:   s.ControllerUUID,
 
170
                metadataKeyCloudInit:  string(userData),
 
171
                metadataKeyEncoding:   "base64",
 
172
                metadataKeySSHKeys:    authKeys,
 
173
        }
 
174
        instanceConfig.Tags = map[string]string{
 
175
                tags.JujuIsController: "true",
 
176
                tags.JujuController:   s.ControllerUUID,
 
177
        }
 
178
        s.WindowsMetadata = map[string]string{
 
179
                metadataKeyWindowsUserdata: string(userData),
 
180
                metadataKeyWindowsSysprep:  fmt.Sprintf(winSetHostnameScript, "juju.*"),
 
181
        }
 
182
        s.Addresses = []network.Address{{
 
183
                Value: "10.0.0.1",
 
184
                Type:  network.IPv4Address,
 
185
                Scope: network.ScopeCloudLocal,
 
186
        }}
 
187
        s.Instance = s.NewInstance(c, "spam")
 
188
        s.BaseInstance = s.Instance.base
 
189
        s.InstName, err = s.Env.namespace.Hostname("42")
 
190
        c.Assert(err, jc.ErrorIsNil)
 
191
 
 
192
        s.StartInstArgs = environs.StartInstanceParams{
 
193
                ControllerUUID: s.ControllerUUID,
 
194
                InstanceConfig: instanceConfig,
 
195
                Tools:          tools,
 
196
                Constraints:    cons,
 
197
                //Placement: "",
 
198
                //DistributionGroup: nil,
 
199
        }
 
200
 
 
201
        s.InstanceType = allInstanceTypes[0]
 
202
 
 
203
        // Storage
 
204
        eUUID := s.Env.Config().UUID()
 
205
        s.BaseDisk = &google.Disk{
 
206
                Id:          1234567,
 
207
                Name:        "home-zone--c930380d-8337-4bf5-b07a-9dbb5ae771e4",
 
208
                Zone:        "home-zone",
 
209
                Status:      google.StatusReady,
 
210
                Size:        1024,
 
211
                Description: eUUID,
 
212
        }
 
213
}
 
214
 
 
215
func (s *BaseSuiteUnpatched) initNet(c *gc.C) {
 
216
        s.Ports = []network.PortRange{{
 
217
                FromPort: 80,
 
218
                ToPort:   80,
 
219
                Protocol: "tcp",
 
220
        }}
 
221
}
 
222
 
 
223
func (s *BaseSuiteUnpatched) setConfig(c *gc.C, cfg *config.Config) {
 
224
        s.Config = cfg
 
225
        ecfg, err := newConfig(cfg, nil)
 
226
        c.Assert(err, jc.ErrorIsNil)
 
227
        s.EnvConfig = ecfg
 
228
        uuid := cfg.UUID()
 
229
        s.Env.uuid = uuid
 
230
        s.Env.ecfg = s.EnvConfig
 
231
        namespace, err := instance.NewNamespace(uuid)
 
232
        c.Assert(err, jc.ErrorIsNil)
 
233
        s.Env.namespace = namespace
 
234
}
 
235
 
 
236
func (s *BaseSuiteUnpatched) NewConfig(c *gc.C, updates testing.Attrs) *config.Config {
 
237
        var err error
 
238
        cfg := testing.ModelConfig(c)
 
239
        cfg, err = cfg.Apply(ConfigAttrs)
 
240
        c.Assert(err, jc.ErrorIsNil)
 
241
        cfg, err = cfg.Apply(updates)
 
242
        c.Assert(err, jc.ErrorIsNil)
 
243
        return cfg
 
244
}
 
245
 
 
246
func (s *BaseSuiteUnpatched) UpdateConfig(c *gc.C, attrs map[string]interface{}) {
 
247
        cfg, err := s.Config.Apply(attrs)
 
248
        c.Assert(err, jc.ErrorIsNil)
 
249
        s.setConfig(c, cfg)
 
250
}
 
251
 
 
252
func (s *BaseSuiteUnpatched) NewBaseInstance(c *gc.C, id string) *google.Instance {
 
253
        diskSpec := google.DiskSpec{
 
254
                Series:     "trusty",
 
255
                SizeHintGB: 15,
 
256
                ImageURL:   "some/image/path",
 
257
                Boot:       true,
 
258
                Scratch:    false,
 
259
                Readonly:   false,
 
260
                AutoDelete: true,
 
261
        }
 
262
        instanceSpec := google.InstanceSpec{
 
263
                ID:                id,
 
264
                Type:              "mtype",
 
265
                Disks:             []google.DiskSpec{diskSpec},
 
266
                Network:           google.NetworkSpec{Name: "somenetwork"},
 
267
                NetworkInterfaces: []string{"somenetif"},
 
268
                Metadata:          s.UbuntuMetadata,
 
269
                Tags:              []string{id},
 
270
        }
 
271
        summary := google.InstanceSummary{
 
272
                ID:        id,
 
273
                ZoneName:  "home-zone",
 
274
                Status:    google.StatusRunning,
 
275
                Metadata:  s.UbuntuMetadata,
 
276
                Addresses: s.Addresses,
 
277
        }
 
278
        return google.NewInstance(summary, &instanceSpec)
 
279
}
 
280
 
 
281
func (s *BaseSuiteUnpatched) NewInstance(c *gc.C, id string) *environInstance {
 
282
        base := s.NewBaseInstance(c, id)
 
283
        return newInstance(base, s.Env)
 
284
}
 
285
 
 
286
type BaseSuite struct {
 
287
        BaseSuiteUnpatched
 
288
 
 
289
        FakeConn    *fakeConn
 
290
        FakeCommon  *fakeCommon
 
291
        FakeEnviron *fakeEnviron
 
292
}
 
293
 
 
294
func (s *BaseSuite) SetUpTest(c *gc.C) {
 
295
        s.BaseSuiteUnpatched.SetUpTest(c)
 
296
 
 
297
        s.FakeConn = &fakeConn{}
 
298
        s.FakeCommon = &fakeCommon{}
 
299
        s.FakeEnviron = &fakeEnviron{}
 
300
 
 
301
        // Patch out all expensive external deps.
 
302
        s.Env.gce = s.FakeConn
 
303
        s.PatchValue(&newConnection, func(google.ConnectionConfig, *google.Credentials) (gceConnection, error) {
 
304
                return s.FakeConn, nil
 
305
        })
 
306
        s.PatchValue(&supportedArchitectures, s.FakeCommon.SupportedArchitectures)
 
307
        s.PatchValue(&bootstrap, s.FakeCommon.Bootstrap)
 
308
        s.PatchValue(&destroyEnv, s.FakeCommon.Destroy)
 
309
        s.PatchValue(&availabilityZoneAllocations, s.FakeCommon.AvailabilityZoneAllocations)
 
310
        s.PatchValue(&buildInstanceSpec, s.FakeEnviron.BuildInstanceSpec)
 
311
        s.PatchValue(&getHardwareCharacteristics, s.FakeEnviron.GetHardwareCharacteristics)
 
312
        s.PatchValue(&newRawInstance, s.FakeEnviron.NewRawInstance)
 
313
        s.PatchValue(&findInstanceSpec, s.FakeEnviron.FindInstanceSpec)
 
314
        s.PatchValue(&getInstances, s.FakeEnviron.GetInstances)
 
315
}
 
316
 
 
317
func (s *BaseSuite) CheckNoAPI(c *gc.C) {
 
318
        c.Check(s.FakeConn.Calls, gc.HasLen, 0)
 
319
}
 
320
 
 
321
// TODO(ericsnow) Move fakeCallArgs, fakeCall, and fake to the testing repo?
 
322
 
 
323
type FakeCallArgs map[string]interface{}
 
324
 
 
325
type FakeCall struct {
 
326
        FuncName string
 
327
        Args     FakeCallArgs
 
328
}
 
329
 
 
330
type fake struct {
 
331
        calls []FakeCall
 
332
 
 
333
        Err        error
 
334
        FailOnCall int
 
335
}
 
336
 
 
337
func (f *fake) err() error {
 
338
        if len(f.calls) != f.FailOnCall+1 {
 
339
                return nil
 
340
        }
 
341
        return f.Err
 
342
}
 
343
 
 
344
func (f *fake) addCall(funcName string, args FakeCallArgs) {
 
345
        f.calls = append(f.calls, FakeCall{
 
346
                FuncName: funcName,
 
347
                Args:     args,
 
348
        })
 
349
}
 
350
 
 
351
func (f *fake) CheckCalls(c *gc.C, expected []FakeCall) {
 
352
        c.Check(f.calls, jc.DeepEquals, expected)
 
353
}
 
354
 
 
355
type fakeCommon struct {
 
356
        fake
 
357
 
 
358
        Arches      []string
 
359
        Arch        string
 
360
        Series      string
 
361
        BSFinalizer environs.BootstrapFinalizer
 
362
        AZInstances []common.AvailabilityZoneInstances
 
363
}
 
364
 
 
365
func (fc *fakeCommon) SupportedArchitectures(env environs.Environ, cons *imagemetadata.ImageConstraint) ([]string, error) {
 
366
        fc.addCall("SupportedArchitectures", FakeCallArgs{
 
367
                "switch": env,
 
368
                "cons":   cons,
 
369
        })
 
370
        return fc.Arches, fc.err()
 
371
}
 
372
 
 
373
func (fc *fakeCommon) Bootstrap(ctx environs.BootstrapContext, env environs.Environ, params environs.BootstrapParams) (*environs.BootstrapResult, error) {
 
374
        fc.addCall("Bootstrap", FakeCallArgs{
 
375
                "ctx":    ctx,
 
376
                "switch": env,
 
377
                "params": params,
 
378
        })
 
379
 
 
380
        result := &environs.BootstrapResult{
 
381
                Arch:     fc.Arch,
 
382
                Series:   fc.Series,
 
383
                Finalize: fc.BSFinalizer,
 
384
        }
 
385
        return result, fc.err()
 
386
}
 
387
 
 
388
func (fc *fakeCommon) Destroy(env environs.Environ) error {
 
389
        fc.addCall("Destroy", FakeCallArgs{
 
390
                "switch": env,
 
391
        })
 
392
        return fc.err()
 
393
}
 
394
 
 
395
func (fc *fakeCommon) AvailabilityZoneAllocations(env common.ZonedEnviron, group []instance.Id) ([]common.AvailabilityZoneInstances, error) {
 
396
        fc.addCall("AvailabilityZoneAllocations", FakeCallArgs{
 
397
                "switch": env,
 
398
                "group":  group,
 
399
        })
 
400
        return fc.AZInstances, fc.err()
 
401
}
 
402
 
 
403
type fakeEnviron struct {
 
404
        fake
 
405
 
 
406
        Inst  *google.Instance
 
407
        Insts []instance.Instance
 
408
        Hwc   *instance.HardwareCharacteristics
 
409
        Spec  *instances.InstanceSpec
 
410
}
 
411
 
 
412
func (fe *fakeEnviron) GetInstances(env *environ) ([]instance.Instance, error) {
 
413
        fe.addCall("GetInstances", FakeCallArgs{
 
414
                "switch": env,
 
415
        })
 
416
        return fe.Insts, fe.err()
 
417
}
 
418
 
 
419
func (fe *fakeEnviron) BuildInstanceSpec(env *environ, args environs.StartInstanceParams) (*instances.InstanceSpec, error) {
 
420
        fe.addCall("BuildInstanceSpec", FakeCallArgs{
 
421
                "switch": env,
 
422
                "args":   args,
 
423
        })
 
424
        return fe.Spec, fe.err()
 
425
}
 
426
 
 
427
func (fe *fakeEnviron) GetHardwareCharacteristics(env *environ, spec *instances.InstanceSpec, inst *environInstance) *instance.HardwareCharacteristics {
 
428
        fe.addCall("GetHardwareCharacteristics", FakeCallArgs{
 
429
                "switch": env,
 
430
                "spec":   spec,
 
431
                "inst":   inst,
 
432
        })
 
433
        return fe.Hwc
 
434
}
 
435
 
 
436
func (fe *fakeEnviron) NewRawInstance(env *environ, args environs.StartInstanceParams, spec *instances.InstanceSpec) (*google.Instance, error) {
 
437
        fe.addCall("NewRawInstance", FakeCallArgs{
 
438
                "switch": env,
 
439
                "args":   args,
 
440
                "spec":   spec,
 
441
        })
 
442
        return fe.Inst, fe.err()
 
443
}
 
444
 
 
445
func (fe *fakeEnviron) FindInstanceSpec(
 
446
        env *environ,
 
447
        ic *instances.InstanceConstraint,
 
448
        imageMetadata []*imagemetadata.ImageMetadata,
 
449
) (*instances.InstanceSpec, error) {
 
450
        fe.addCall("FindInstanceSpec", FakeCallArgs{
 
451
                "switch":        env,
 
452
                "ic":            ic,
 
453
                "imageMetadata": imageMetadata,
 
454
        })
 
455
        return fe.Spec, fe.err()
 
456
}
 
457
 
 
458
// TODO(ericsnow) Refactor fakeConnCall and fakeConn to embed fakeCall and fake.
 
459
 
 
460
type fakeConnCall struct {
 
461
        FuncName string
 
462
 
 
463
        ID           string
 
464
        IDs          []string
 
465
        ZoneName     string
 
466
        ZoneNames    []string
 
467
        Prefix       string
 
468
        Statuses     []string
 
469
        InstanceSpec google.InstanceSpec
 
470
        FirewallName string
 
471
        PortRanges   []network.PortRange
 
472
        Region       string
 
473
        Disks        []google.DiskSpec
 
474
        VolumeName   string
 
475
        InstanceId   string
 
476
        Mode         string
 
477
}
 
478
 
 
479
type fakeConn struct {
 
480
        Calls []fakeConnCall
 
481
 
 
482
        Inst       *google.Instance
 
483
        Insts      []google.Instance
 
484
        PortRanges []network.PortRange
 
485
        Zones      []google.AvailabilityZone
 
486
 
 
487
        GoogleDisks   []*google.Disk
 
488
        GoogleDisk    *google.Disk
 
489
        AttachedDisk  *google.AttachedDisk
 
490
        AttachedDisks []*google.AttachedDisk
 
491
 
 
492
        Err        error
 
493
        FailOnCall int
 
494
}
 
495
 
 
496
func (fc *fakeConn) err() error {
 
497
        if len(fc.Calls) != fc.FailOnCall+1 {
 
498
                return nil
 
499
        }
 
500
        return fc.Err
 
501
}
 
502
 
 
503
func (fc *fakeConn) VerifyCredentials() error {
 
504
        fc.Calls = append(fc.Calls, fakeConnCall{
 
505
                FuncName: "",
 
506
        })
 
507
        return fc.err()
 
508
}
 
509
 
 
510
func (fc *fakeConn) Instance(id, zone string) (google.Instance, error) {
 
511
        fc.Calls = append(fc.Calls, fakeConnCall{
 
512
                FuncName: "Instance",
 
513
                ID:       id,
 
514
                ZoneName: zone,
 
515
        })
 
516
        return *fc.Inst, fc.err()
 
517
}
 
518
 
 
519
func (fc *fakeConn) Instances(prefix string, statuses ...string) ([]google.Instance, error) {
 
520
        fc.Calls = append(fc.Calls, fakeConnCall{
 
521
                FuncName: "Instances",
 
522
                Prefix:   prefix,
 
523
                Statuses: statuses,
 
524
        })
 
525
        return fc.Insts, fc.err()
 
526
}
 
527
 
 
528
func (fc *fakeConn) AddInstance(spec google.InstanceSpec, zones ...string) (*google.Instance, error) {
 
529
        fc.Calls = append(fc.Calls, fakeConnCall{
 
530
                FuncName:     "AddInstance",
 
531
                InstanceSpec: spec,
 
532
                ZoneNames:    zones,
 
533
        })
 
534
        return fc.Inst, fc.err()
 
535
}
 
536
 
 
537
func (fc *fakeConn) RemoveInstances(prefix string, ids ...string) error {
 
538
        fc.Calls = append(fc.Calls, fakeConnCall{
 
539
                FuncName: "RemoveInstances",
 
540
                Prefix:   prefix,
 
541
                IDs:      ids,
 
542
        })
 
543
        return fc.err()
 
544
}
 
545
 
 
546
func (fc *fakeConn) Ports(fwname string) ([]network.PortRange, error) {
 
547
        fc.Calls = append(fc.Calls, fakeConnCall{
 
548
                FuncName:     "Ports",
 
549
                FirewallName: fwname,
 
550
        })
 
551
        return fc.PortRanges, fc.err()
 
552
}
 
553
 
 
554
func (fc *fakeConn) OpenPorts(fwname string, ports ...network.PortRange) error {
 
555
        fc.Calls = append(fc.Calls, fakeConnCall{
 
556
                FuncName:     "OpenPorts",
 
557
                FirewallName: fwname,
 
558
                PortRanges:   ports,
 
559
        })
 
560
        return fc.err()
 
561
}
 
562
 
 
563
func (fc *fakeConn) ClosePorts(fwname string, ports ...network.PortRange) error {
 
564
        fc.Calls = append(fc.Calls, fakeConnCall{
 
565
                FuncName:     "ClosePorts",
 
566
                FirewallName: fwname,
 
567
                PortRanges:   ports,
 
568
        })
 
569
        return fc.err()
 
570
}
 
571
 
 
572
func (fc *fakeConn) AvailabilityZones(region string) ([]google.AvailabilityZone, error) {
 
573
        fc.Calls = append(fc.Calls, fakeConnCall{
 
574
                FuncName: "AvailabilityZones",
 
575
                Region:   region,
 
576
        })
 
577
        return fc.Zones, fc.err()
 
578
}
 
579
 
 
580
func (fc *fakeConn) CreateDisks(zone string, disks []google.DiskSpec) ([]*google.Disk, error) {
 
581
        fc.Calls = append(fc.Calls, fakeConnCall{
 
582
                FuncName: "CreateDisks",
 
583
                ZoneName: zone,
 
584
                Disks:    disks,
 
585
        })
 
586
        return fc.GoogleDisks, fc.err()
 
587
}
 
588
 
 
589
func (fc *fakeConn) Disks(zone string) ([]*google.Disk, error) {
 
590
        fc.Calls = append(fc.Calls, fakeConnCall{
 
591
                FuncName: "Disks",
 
592
                ZoneName: zone,
 
593
        })
 
594
        return fc.GoogleDisks, fc.err()
 
595
}
 
596
 
 
597
func (fc *fakeConn) RemoveDisk(zone, id string) error {
 
598
        fc.Calls = append(fc.Calls, fakeConnCall{
 
599
                FuncName: "RemoveDisk",
 
600
                ZoneName: zone,
 
601
                ID:       id,
 
602
        })
 
603
        return fc.err()
 
604
}
 
605
 
 
606
func (fc *fakeConn) Disk(zone, id string) (*google.Disk, error) {
 
607
        fc.Calls = append(fc.Calls, fakeConnCall{
 
608
                FuncName: "Disk",
 
609
                ZoneName: zone,
 
610
                ID:       id,
 
611
        })
 
612
        return fc.GoogleDisk, fc.err()
 
613
}
 
614
 
 
615
func (fc *fakeConn) AttachDisk(zone, volumeName, instanceId string, mode google.DiskMode) (*google.AttachedDisk, error) {
 
616
        fc.Calls = append(fc.Calls, fakeConnCall{
 
617
                FuncName:   "AttachDisk",
 
618
                ZoneName:   zone,
 
619
                VolumeName: volumeName,
 
620
                InstanceId: instanceId,
 
621
                Mode:       string(mode),
 
622
        })
 
623
        return fc.AttachedDisk, fc.err()
 
624
}
 
625
 
 
626
func (fc *fakeConn) DetachDisk(zone, instanceId, volumeName string) error {
 
627
        fc.Calls = append(fc.Calls, fakeConnCall{
 
628
                FuncName:   "DetachDisk",
 
629
                ZoneName:   zone,
 
630
                InstanceId: instanceId,
 
631
                VolumeName: volumeName,
 
632
        })
 
633
        return fc.err()
 
634
}
 
635
 
 
636
func (fc *fakeConn) InstanceDisks(zone, instanceId string) ([]*google.AttachedDisk, error) {
 
637
        fc.Calls = append(fc.Calls, fakeConnCall{
 
638
                FuncName:   "InstanceDisks",
 
639
                ZoneName:   zone,
 
640
                InstanceId: instanceId,
 
641
        })
 
642
        return fc.AttachedDisks, fc.err()
 
643
}
 
644
 
 
645
func (fc *fakeConn) WasCalled(funcName string) (bool, []fakeConnCall) {
 
646
        var calls []fakeConnCall
 
647
        called := false
 
648
        for _, call := range fc.Calls {
 
649
                if call.FuncName == funcName {
 
650
                        called = true
 
651
                        calls = append(calls, call)
 
652
                }
 
653
        }
 
654
        return called, calls
 
655
}