1
// Copyright 2015 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
10
gc "gopkg.in/check.v1"
12
"github.com/juju/errors"
13
"github.com/juju/juju/cloudconfig/instancecfg"
14
"github.com/juju/juju/constraints"
15
"github.com/juju/juju/environs"
16
"github.com/juju/juju/environs/config"
17
"github.com/juju/juju/instance"
18
"github.com/juju/juju/network"
19
"github.com/juju/juju/provider/common"
20
"github.com/juju/juju/provider/rackspace"
21
"github.com/juju/juju/status"
22
"github.com/juju/juju/storage"
23
"github.com/juju/juju/testing"
24
"github.com/juju/juju/tools"
25
"github.com/juju/utils/ssh"
26
"github.com/juju/version"
29
type environSuite struct {
31
environ environs.Environ
32
innerEnviron *fakeEnviron
35
var _ = gc.Suite(&environSuite{})
37
func (s *environSuite) SetUpTest(c *gc.C) {
38
s.innerEnviron = new(fakeEnviron)
39
s.environ = rackspace.NewEnviron(s.innerEnviron)
42
func (s *environSuite) TestBootstrap(c *gc.C) {
43
s.PatchValue(rackspace.Bootstrap, func(ctx environs.BootstrapContext, env environs.Environ, args environs.BootstrapParams) (*environs.BootstrapResult, error) {
44
return s.innerEnviron.Bootstrap(ctx, args)
46
s.environ.Bootstrap(nil, environs.BootstrapParams{
47
ControllerConfig: testing.FakeControllerConfig(),
49
c.Check(s.innerEnviron.Pop().name, gc.Equals, "Bootstrap")
52
func (s *environSuite) TestStartInstance(c *gc.C) {
53
configurator := &fakeConfigurator{}
54
s.PatchValue(rackspace.WaitSSH, func(stdErr io.Writer, interrupted <-chan os.Signal, client ssh.Client, checkHostScript string, inst common.Addresser, timeout environs.BootstrapDialOpts) (addr string, err error) {
55
addresses, err := inst.Addresses()
59
return addresses[0].Value, nil
61
s.PatchValue(rackspace.NewInstanceConfigurator, func(host string) common.InstanceConfigurator {
64
config, err := config.New(config.UseDefaults, map[string]interface{}{
67
"uuid": testing.ModelTag.Id(),
68
"controller-uuid": testing.ModelTag.Id(),
69
"authorized-keys": "key",
71
c.Assert(err, gc.IsNil)
72
err = s.environ.SetConfig(config)
73
c.Assert(err, gc.IsNil)
74
_, err = s.environ.StartInstance(environs.StartInstanceParams{
75
InstanceConfig: &instancecfg.InstanceConfig{},
76
Tools: tools.List{&tools.Tools{
77
Version: version.Binary{Series: "trusty"},
80
c.Check(err, gc.IsNil)
81
c.Check(s.innerEnviron.Pop().name, gc.Equals, "StartInstance")
82
dropParams := configurator.Pop()
83
c.Check(dropParams.name, gc.Equals, "DropAllPorts")
84
c.Check(dropParams.params[1], gc.Equals, "1.1.1.1")
87
type methodCall struct {
92
type fakeEnviron struct {
94
methodCalls []methodCall
97
func (p *fakeEnviron) Push(name string, params ...interface{}) {
98
p.methodCalls = append(p.methodCalls, methodCall{name, params})
101
func (p *fakeEnviron) Pop() methodCall {
102
m := p.methodCalls[0]
103
p.methodCalls = p.methodCalls[1:]
107
func (p *fakeEnviron) Open(cfg *config.Config) (environs.Environ, error) {
112
func (e *fakeEnviron) Create(args environs.CreateParams) error {
113
e.Push("Create", args)
117
func (e *fakeEnviron) PrepareForBootstrap(ctx environs.BootstrapContext) error {
118
e.Push("PrepareForBootstrap", ctx)
122
func (e *fakeEnviron) Bootstrap(ctx environs.BootstrapContext, params environs.BootstrapParams) (*environs.BootstrapResult, error) {
123
e.Push("Bootstrap", ctx, params)
127
func (e *fakeEnviron) StartInstance(args environs.StartInstanceParams) (*environs.StartInstanceResult, error) {
128
e.Push("StartInstance", args)
129
return &environs.StartInstanceResult{
130
Instance: &fakeInstance{},
134
func (e *fakeEnviron) StopInstances(ids ...instance.Id) error {
135
e.Push("StopInstances", ids)
139
func (e *fakeEnviron) AllInstances() ([]instance.Instance, error) {
140
e.Push("AllInstances")
144
func (e *fakeEnviron) MaintainInstance(args environs.StartInstanceParams) error {
145
e.Push("MaintainInstance", args)
149
func (e *fakeEnviron) Config() *config.Config {
153
func (e *fakeEnviron) ConstraintsValidator() (constraints.Validator, error) {
154
e.Push("ConstraintsValidator")
158
func (e *fakeEnviron) SetConfig(cfg *config.Config) error {
163
func (e *fakeEnviron) Instances(ids []instance.Id) ([]instance.Instance, error) {
164
e.Push("Instances", ids)
165
return []instance.Instance{&fakeInstance{}}, nil
168
func (e *fakeEnviron) ControllerInstances(_ string) ([]instance.Id, error) {
169
e.Push("ControllerInstances")
173
func (e *fakeEnviron) Destroy() error {
178
func (e *fakeEnviron) DestroyController(controllerUUID string) error {
183
func (e *fakeEnviron) OpenPorts(ports []network.PortRange) error {
184
e.Push("OpenPorts", ports)
188
func (e *fakeEnviron) ClosePorts(ports []network.PortRange) error {
189
e.Push("ClosePorts", ports)
193
func (e *fakeEnviron) Ports() ([]network.PortRange, error) {
198
func (e *fakeEnviron) Provider() environs.EnvironProvider {
203
func (e *fakeEnviron) PrecheckInstance(series string, cons constraints.Value, placement string) error {
204
e.Push("PrecheckInstance", series, cons, placement)
208
func (e *fakeEnviron) StorageProviderTypes() []storage.ProviderType {
209
e.Push("StorageProviderTypes")
213
func (e *fakeEnviron) StorageProvider(t storage.ProviderType) (storage.Provider, error) {
214
e.Push("StorageProvider", t)
215
return nil, errors.NotImplementedf("StorageProvider")
218
type fakeConfigurator struct {
219
methodCalls []methodCall
222
func (p *fakeConfigurator) Push(name string, params ...interface{}) {
223
p.methodCalls = append(p.methodCalls, methodCall{name, params})
226
func (p *fakeConfigurator) Pop() methodCall {
227
m := p.methodCalls[0]
228
p.methodCalls = p.methodCalls[1:]
232
func (e *fakeConfigurator) DropAllPorts(exceptPorts []int, addr string) error {
233
e.Push("DropAllPorts", exceptPorts, addr)
237
func (e *fakeConfigurator) ConfigureExternalIpAddress(apiPort int) error {
238
e.Push("ConfigureExternalIpAddress", apiPort)
242
func (e *fakeConfigurator) ChangePorts(ipAddress string, insert bool, ports []network.PortRange) error {
243
e.Push("ChangePorts", ipAddress, insert, ports)
247
func (e *fakeConfigurator) FindOpenPorts() ([]network.PortRange, error) {
248
e.Push("FindOpenPorts")
252
func (e *fakeConfigurator) AddIpAddress(nic string, addr string) error {
253
e.Push("AddIpAddress", nic, addr)
257
func (e *fakeConfigurator) ReleaseIpAddress(addr string) error {
258
e.Push("AddIpAddress", addr)
262
type fakeInstance struct {
263
methodCalls []methodCall
266
func (p *fakeInstance) Push(name string, params ...interface{}) {
267
p.methodCalls = append(p.methodCalls, methodCall{name, params})
270
func (p *fakeInstance) Pop() methodCall {
271
m := p.methodCalls[0]
272
p.methodCalls = p.methodCalls[1:]
276
func (e *fakeInstance) Id() instance.Id {
278
return instance.Id("")
281
func (e *fakeInstance) Status() instance.InstanceStatus {
283
return instance.InstanceStatus{
284
Status: status.StatusProvisioning,
285
Message: "a message",
289
func (e *fakeInstance) Refresh() error {
294
func (e *fakeInstance) Addresses() ([]network.Address, error) {
296
return []network.Address{network.Address{
298
Type: network.IPv4Address,
299
Scope: network.ScopePublic,
303
func (e *fakeInstance) OpenPorts(machineId string, ports []network.PortRange) error {
304
e.Push("OpenPorts", machineId, ports)
308
func (e *fakeInstance) ClosePorts(machineId string, ports []network.PortRange) error {
309
e.Push("ClosePorts", machineId, ports)
313
func (e *fakeInstance) Ports(machineId string) ([]network.PortRange, error) {
314
e.Push("Ports", machineId)